This is /home/nick/riscos/2.95/riscos-dist/!gcc/docs/gpc, produced by
makeinfo version 4.2 from doc/gpc.texi.

INFO-DIR-SECTION GNU programming tools
START-INFO-DIR-ENTRY
* GPC: (gpc).                   The GNU Pascal Compiler.
END-INFO-DIR-ENTRY
INFO-DIR-SECTION Individual utilities
START-INFO-DIR-ENTRY
* GPC: (gpc)Invoking GPC.       The GNU Pascal Compiler.
END-INFO-DIR-ENTRY

   This file documents the GNU Pascal Compiler.

   Copyright (C) 1988, 1996-2000 Free Software Foundation, Inc.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the sections entitled "GNU General Public License", "The GNU
Project", "The GNU Manifesto" and "Funding for Free Software" are
included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that the sections entitled "GNU General Public
License", "The GNU Project", "The GNU Manifesto" and "Funding for Free
Software" and this permission notice, may be included in translations
approved by the Free Software Foundation instead of in the original
English.


File: gpc,  Node: Top,  Next: Welcome,  Up: (dir)

GNU Pascal
**********

   This manual documents how to run, install and maintain the GNU Pascal
Compiler (GPC), as well as its new features and incompatibilities, and
how to report bugs.  It corresponds to GPC version 20001218 (GCC
version 2.95.x).

* Menu:

Introduction:

* Welcome::           Welcome to GNU Pascal...
* Highlights::        Some of GPC's most interesting features.
* News::              New Features of GNU Pascal.
* FAQ::               The GNU Pascal Frequently Asked Questions List.

Installation:

* Installation::      How to download, compile and install GNU Pascal.

Using GNU Pascal:

* Borland Pascal::    A QuickStart Guide from Borland Pascal to GNU Pascal.
* Invoking GPC::      Command Line Options supported by GNU Pascal.
* Programming::       The Programmer's Guide to GPC.
* Reference::         The Alphabetical GPC Language Reference.
* Keywords::          Pascal keywords and operators supported by GNU Pascal.
* Support::           Where to get support for GNU Pascal; how to report bugs.

Development:

* To Do::             The GNU Pascal To-Do List.
* Internals::         How to get more information from the GPC source itself.

Appendix:

* Contributors::      Contributors to GNU Pascal.
* Copying::           The GNU General Public License -- Your rights and
                      duties when using GPC.
* GNU::               The GNU Project.

* GPC Index::         Index of concepts and symbol names (incomplete).


File: gpc,  Node: Welcome,  Next: Highlights,  Prev: Top,  Up: Top

Welcome to GNU Pascal...
************************

   ...  the free 32/64-bit Pascal compiler of the GNU Compiler
Collection (GNU CC or GCC). It combines a Pascal front-end with the
proven GCC back-end for code generation and optimization.  Other
compilers in the collection currently include compilers for the Ada, C,
C++, Objective C, Chill, FORTRAN, and Java languages. Unlike utilities
such as p2c, this is a true compiler, not just a converter.

   This version of GPC corresponds to GCC version 2.95.x.

   The purpose of the GNU Pascal project is to produce a Pascal
compiler (called GNU Pascal or GPC) which

   * combines the clarity of Pascal with powerful tools suitable for
     real-life programming,

   * supports both the Pascal standard and the Extended Pascal standard
     as defined by ISO, ANSI and IEEE (ISO 7185:1990, ISO/IEC
     10206:1991, ANSI/IEEE 770X3.160-1989),

   * supports other Pascal standards (UCSD Pascal, Borland Pascal,
     Pascal-SC) in so far as this serves the goal of clarity and
     usability,

   * may be distributed under GNU license conditions, and

   * can generate code for and run on any computer for which the GNU C
     compiler can generate code and run on.

   Pascal was originally designed for teaching. GNU Pascal provides a
smooth way to proceed to challenging programming tasks without learning
a completely different language.

   The current release implements Standard Pascal (ISO 7185, level 1),
a large subset of Extended Pascal (ISO 10206, aiming for full
compliance), is highly compatible to Borland Pascal (version 7.0) with
some Delphi extensions, and provides a lot of useful GNU extensions.

   This manual contains

   * an overview of some of GPC's most interesting features, see *Note
     Highlights::,

   * a list of new features since the last release, see *Note News::,

   * the GNU Pascal Frequently Asked Questions List, see *Note FAQ::,

   * installation instructions, see *Note Installation::,

   * a QuickStart Guide for programmers used to the Turbo Pascal/Borland
     Pascal compiler, see *Note Borland Pascal::,

   * a list of command-line options to invoke the compiler, see *Note
     Invoking GPC::,

   * the Programmer's Guide to GPC, describing the Pascal programming
     language in general and GPC specifc aspects, see *Note
     Programming::,

   * the alphabetical GPC language reference, see *Note Reference::,

   * a list of keywords and operators supported by GNU Pascal, see
     *Note Keywords::,

   * information on how to report bugs in GNU Pascal and how to get
     support, see *Note Support::,

   * the list of known bugs and things to do, also listing bugs fixed
     and features implemented recently, see *Note To Do::,

   * some information for those who are interested in how GNU Pascal
     works internally, see *Note Internals::,

   * a list of contributors which tells you who devloped and is
     maintaining GNU Pascal, see *Note Contributors::,

   * the GNU General Public License which informs you about your rights
     and responsibilites when using, modifying and distributing GNU
     Pascal, see *Note Copying::,

   * and other texts about Free Software and the GNU Project intended to
     answer questions like "what is GNU?" you might have in mind now,
     see *Note GNU::.

   If you are familiar with Standard Pascal (ISO 7185) programming, you
can probably just go ahead and try to compile your programs. Also, most
of the ISO Extended Pascal Standard (ISO 10206) is implemented into GNU
Pascal. The Extended Pascal features still missing from GPC are
`qualified' module import, `protected' module export variables, set
types with variable bounds, structured value initializers and
expressions as subrange lower bounds.

   If you are a Borland Pascal programmer, you should probably start
reading the QuickStart guide from BP to GNU Pascal, see *Note Borland
Pascal::. If you are curious about the new features GPC offers, you can
get an idea in the overview of GPC highlights (*note Highlights::), and
read in more detail about them in the Programmer's Guide to GPC (*note
Programming::) and in the alphabetical GPC Language Reference (*note
Reference::).

   And, please, think about how you can contribute to the GNU Pascal
project, too. Please support our work by contributing yours in form of
example programs, bug reports, documentation, or even actual
improvements of the compiler.

   All trademarks used in this manual are properties of their
respective owners.


File: gpc,  Node: Highlights,  Next: News,  Prev: Welcome,  Up: Top

1 Some of GPC's most interesting features.
******************************************

   The GNU Pascal Compiler (GPC) is, as the name says, the Pascal
compiler of the GNU (`gnu.html' on GPC's WWW home page) family. This
means:

   * GPC is a 32/64 bit compiler,

   * does not have limits like the 64 kB or 640 kB limit known from
     certain operating systems - even on those systems -,

   * runs on all operating systems supported by GNU C, including

        - Linux (http://www.linux.org) on Intel, Alpha, and all other
          supported types of hardware,

        - the BSD family: FreeBSD (http://www.freebsd.org), NetBSD
          (http://www.netbsd.org), OpenBSD (http://www.openbsd.org),

        - DOS with 32 bits, using DJGPP (http://www.delorie.com/djgpp/)
          or EMX
          (http://www.leo.org/pub/comp/os/os2/leo/gnu/emx+gcc/index.html),

        - MS-Windows 9x/NT, using CygWin
          (http://sourceware.cygnus.com/cygwin/) or mingw32
          (http://agnes.dida.physik.uni-essen.de/~janjaap/mingw32/),

        - OS/2 with EMX
          (http://www.leo.org/pub/comp/os/os2/leo/gnu/emx+gcc/index.html),

        - MIPS-SGI-IRIX,

        - Alpha-DEC-OSF,

        - Sparc-Sun-Solaris,

        - HP/UX
      and more,

   * can act as a native or as a cross compiler between all supported
     systems,

   * produces highly optimized code for all these systems,

   * is Free Software
     (http://home.pages.de/~GNU/philosophy/free-sw.html) (Open-Source
     Software (http://www.opensource.org)) according to the *GNU
     General Public License* (http://www.gnu.org/copyleft/gpl.html)
     (see also GNU (`gnu.html' on GPC's WWW home page) for remarks and
     translations),

   * is compatible to other GNU languages and tools such as GNU C and
     the GNU debugger.

   The compiler supports the following language standards and
quasi-standards:

   * ISO-7185 Standard Pascal (`misc.html#ISO' on GPC's WWW home page),

   * most of ISO-10206 Extended Pascal (`misc.html#ISO' on GPC's WWW
     home page),

   * Borland Pascal 7.0,

   * parts of Pascal-SC (PXSC).

   Some highlights:

   * From Standard Pascal: Many popular Pascal compilers claim to
     extend Standard Pascal but miss these important features.

        - Conformant array parameters - the standardized and
          comfortable way to pass arrays of varying size to procedures
          and functions. [Example (conformantdemo.pas)]

        - Passing local procedures as procedural parameters - with full
          access to all variables of the "parent" procedure. [Example
          (iteratordemo.pas)]

        - Automatic file buffers and standard `Get' and `Put'
          procedures. Read ahead from files without temporary variables.
          [Example (filebuf1demo.pas)] This allows you, for instance, to
          validate numeric input from text files before reading without
          conversion through strings. [Example (filebuf2demo.pas)]

        - True packed records and arrays. Pack 8 Booleans into 1 byte.
          [Example (packdemo.pas)]

        - Internal files. You don't have to worry about creating
          temporary file names and erasing the files later.  [Example
          (intfiledemo.pas)]

        - Global `goto'. (Yes, `goto' has its place when it is not
          restricted to stay in the current routine.)  [Example
          (parserdemo.pas)]

        - Automatically set discriminants of variant records in `New'.
          [Example (variantdemo.pas)]

        - Sets of arbitrary size.  [Example (bigsetsdemo.pas)]

   * From Extended Pascal:

        - Strings of arbitrary length.  [Example (stringschemademo.pas)]

        - `ReadStr' and `WriteStr'.  Read from and write to strings
          with the full comfort of `ReadLn'/`WriteLn'. [Example
          (rwstringdemo.pas)]

        - System-independent date/time routines.  [Example
          (datetimedemo.pas)]

        - Set member iteration:
          `for Ch in ['A' .. 'Z', 'a' .. 'z'] do ...' [Example
          (bigsetsdemo.pas)]

        - Set extensions (symmetric difference, `Card')

        - Generalized `Succ' and `Pred' functions
          (`foo := Succ (bar, 5);').

        - Complex numbers.  [Example (mandelbrot.pas)] [Example
          (parserdemo.pas)]

        - Exponentiation operators (`pow' and `**') for real and
          complex numbers.

        - Initialized variables.  [Example (initvardemo.pas)]

        - Functions can return array or record values.

        - Return value variables.  [Example (returnvardemo.pas)]

        - Modules.

        - Non-decimal numbers in base 2 through 36: `base#number'.

        - `MinReal', `MaxReal', `EpsReal', `MaxChar' constants.

        - Schemata - the Pascal way to get dynamic arrays without dirty
          tricks. [Example (schemademo.pas)]

        - Local variables may have dynamic size.  [Example
          (dynamicarraydemo.pas)]

        - Array Slice Acces - access parts of an array as a smaller
          array, even on the left side of an assignment [Example
          (arrayslicedemo.pas)]

   * Compatible to Borland Pascal 7.0 with objects (BP):

        - Supports units, objects, ..., and makes even things like
          `absolute' variables portable.  [Example (absdemo.pas)]

        - Comes with portable versions of the BP standard units with
          full source.

        - True network-transparent CRT unit: You can run your CRT
          applications locally or while being logged in remotely,
          without any need to worry about different terminal types.
          Compatible to BP's unit, but with many extensions, such as
          overlapping windows.  [Example (crtdemo.pas)]

        - Fully functional GUI (X11) version of CRT (also completely
          network transparent).

        - The `Random' function can produce the same sequence of
          pseudo-random numbers as BP does - if you need that instead
          of the much more elaborate default algorithm.

        - Supports BP style procedural variables as well as Standard
          Pascal's procedural parameters.  [Example (procvardemo.pas)]

        - A `Ports' unit lets you access CPU I/O ports on systems where
          this makes sense. [Example (portdemo.pas)]

        - Special compatibility features to help migrating from BP to
          GPC, like a `GPC for BP' unit which provides some of GPC's
          features under BP, and some routines to access sets of large
          memory blocks in a uniform way under GPC and BP (even in real
          mode).  [Example (bigmemdemo.pas)]

   * From Pascal-SC (PXSC):

        - User-definable operators. Add your vectors with `+'.

   * Carefully designed GNU extensions help you to make your real-world
     programs portable:

        - 64-bit signed and unsigned integer types.

        - A Delphi-compatible `SetLength' procedure for strings makes
          it unnecessary to use dirty tricks like assignments to the
          "zeroth character".

        - Special types guarantee compatibility to other GNU languages
          such as GNU C. Directives like `{$L foo.c}' make it easy to
          maintain projects written in multiple languages, e.g.,
          including code written in other languages into Pascal programs
          [Example (Pascal part) (c_gpc.pas)] [Example (C part)
          (c_gpc_c.c)],

        - or including Pascal code into programs written in other
          languages.  [Example (Pascal part) (gpc_c_pas.pas)] [Example
          (Pascal unit) (gpc_c_unit.pas)] [Example (C part) (gpc_c_c.c)]

        - Extensions like `BitSizeOf' and `ConvertFromBigEndian' help
          you to deal with different data sizes and endianesses.
          [Example (endiandemo.pas)]

        - Little somethings like `DirSeparator', `PathSeparator',
          `GetTempDirectory' help you to write programs that look and
          feel "at home" on all operating systems.

        - The `PExecute' routine lets you execute child processes in a
          portable way that takes full advantage of multitasking
          environments. [Example (pexecutedemo.pas)]

        - The GNU GetOpt routines give you comfortable access to
          Unix-style short and long command-line options with and
          without arguments. [Example (getoptdemo.pas)]

        - Routines like `FSplit' or `FSearch' or `FExpand' know about
          the specifics of the various different operating systems.
          [Example (fexpanddemo.pas)]

        - The `FormatTime' function lets you format date and time
          values, according to various formatting rules.  [Example
          (formattimedemo.pas)]

   * Useful and portable GNU standard units:

        - A `Pipe' unit gives you inter-process communication even
          under plain DOS. [Example (pipedemo.pas)] [Demo process for
          the example (demoproc.pas)]

        - With the `RegEx' unit you can do searches with "regular
          expressions". [Example (regexdemo.pas)]

        - The GNU MultiPrecision (`GMP') unit allows you to do
          arithmetics with integer, real, and rational numbers of
          arbitrary precision.  [Example: factorial (factorial.pas)]
          [Example: fibonacci (fibonacci.pas)] [Example: power
          (power.pas)] [Example: real power (realpower.pas)] [Example:
          pi (pi.pas)]

        - Posix functions like `ReadDir', `StatFS' or `FileLock'
          provide an efficient, easy-to-use and portable interface to
          the operating system. [Example (readdirdemo.pas)] [Example
          (statfsdemo.pas)] [Example (filelockdemo.pas)]

        - A `DosUnix' unit compensates for some of the
          incompatibilities between two families of operating systems.
          [Example (dosunixdemo.pas)]

        - An `MD5' unit to compute MD5 message digests, according to
          RFC 1321. [Example (md5demo.pas)]

        - A `FileUtils' unit which provides some higher-level file and
          directory handling routines.  [Example (findfilesdemo.pas)]

        - A `StringUtils' unit which provides some higher-level string
          handling routines.  [Example (stringhashdemo.pas)]

        - A `Trap' unit to trap runtime errors and handle them within
          your program. [Example (trapdemo.pas)]

   The demo programs mentioned above are available both on the WWW and
in GPC source and binary distributions.

   Disadvantages:

   * The GNU debugger (GDB) does not yet understand Pascal syntax and
     types; you have to use C syntax when debugging Pascal programs
     with GDB.

   * With GPC you get longer compilation times than with, e.g., Borland
     Pascal.

   *Co-workers welcome!*

   Able, committed programmers are always welcome in the GNU Pascal
team. If you want to be independent of companies that you must pay for
getting a compiler with more restrictive licensing conditions that only
runs on _one_ operating system, be invited to join the development
team, *Note Contributors::.


File: gpc,  Node: News,  Next: FAQ,  Prev: Highlights,  Up: Top

2 New Features of GNU Pascal.
*****************************

   There's a large number of bug fixes, too many to mention here. They
are listed in the `Fixed Bugs' section of the GPC To-Do list, *Note
Fixed Bugs::.

   The most important bugs fixed include the unit/module initialization
done in the wrong order, and not working at all on some systems, the
global goto bug, some "two-unit bugs" and a number of BP compatibility
issues.

   There's a number of new or changed features which are listed in the
following sections. Features without further description refer to new
routines or options.

* Menu:

* News - General Changes And Possible Incompatibilies with Previous Versions::
* News - Command Line Options and Compiler Directives::
* News - Compiler and RTS Built-in Declarations::
* News - Units::
* News - GPC Manual::
* News - Demo Programs::
* News - Test Suite::
* Legend::


File: gpc,  Node: News - General Changes And Possible Incompatibilies with Previous Versions,  Next: News - Command Line Options and Compiler Directives,  Up: News

2.1 General Changes And Possible Incompatibilies with Previous Versions
=======================================================================

   This release of GPC has been cleaned up substantially. Consequently,
a few old and obsolete features have been dropped or replaced by
cleaner, more flexible or otherwise more useful ones. This might lead
to minor problems with old programs, but we suppose they're very rare
(many programmers might not even know about the old features) and easy
to overcome. The most important ones are listed here, the rest of them
is contained in the following sections and marked with `(@)'.

   * The executables `bpc', `pc' and `epc' have been dropped. What they
     did was equivalent to `gpc --borland-pascal', `gpc
     --standard-pascal' or `gpc --extended-pascal', respectively, and
     you can use these forms now. If you need them often, you can put
     them in scripts or aliases called `bpc' etc., of course.

   * `asmname' in variable and constant declarations must now come
     after the type (e.g. `var foo : Integer = 42; asmname 'bar';').
     Furthermore, `asmname' doesn't imply `external' anymore for
     variables.

   * The internal file handling in the RTS was changed from using
     `FILE *' pointers to integer file handles, to make it more
     efficient and to get rid of some problems. Accordingly, the
     `CFile' field in `BindingType' was replaced by a `Handle' field,
     the `AssignCFile' procedure by an `AssignHandle' procedure, and
     the `GetFile' function was removed (a substitute is the function
     `FileHandle' which has already existed in previous releases).

   * The option `--no-nested-comments' (to allow comments like `{ *)'
     as the standard requires) has been renamed to `--mixed-comments'
     (note the inverted value). Accordingly, the compiler directives
     `{$N+}' and `{$N-}' have been renamed to `{$no-mixed-comments}' and
     `{$mixed-comments}'. The default, when no dialect options are
     given, is still `--no-mixed-comments' (i.e., what used to be
     `--nested-comments').

   * A new option `--nested-comments' to allow real nested comments
     like `{ { } }' (also available as a compiler switch, like almost
     all command-line options). Note the new meaning of this switch, so
     if you used it before, you'll probably have to change it to
     `--no-mixed-comments' (see above). If nested comments are enabled,
     comments are also allowed within compiler directives and macros -
     however, compiler directives within other compiler directives are
     still not allowed, and compiler directives within comments are, of
     course, still ignored.

   * C style character escapes (`\n', `\007' etc.) are now the default
     for strings enclosed in double quotes, while single quoted strings
     do not allow them (according to the standard).  Accordingly, a
     verbatim `"' in a double quoted string is now obtained with `\"'
     rather than `""' (but a verbatim `'' in a single quoted string
     still with `''', of course). Therefore, the option
     `--[no-]char-escapes' and the compiler directives `{$E+}'/`{$E-}'
     have been dropped.  If you used these features, please change to
     the appropriate kind of quotes.

   * Macros are no more expanded in `--borland-pascal' and `--delphi'
     modes. Expanding them causes a few problems with strange sources
     written for BP which use the same name for a conditional define
     and an identifier. Macros can be turned on/off, independently of
     the dialect, with the new switches `--[no-]macros'. (B)

   * Macros and conditionals defined with `{$define}' are now
     case-insensitive. (B) Macros and conditionals defined with
     `--define' on the command line are still case-sensitive for
     compatibility to other GNU compilers. In addition, GPC provides
     `{$csdefine}' or `--csdefine' and `{$cidefine}' or `--cidefine' to
     define case sensitive or insensitive macros or conditionals,
     respectively. If you have defined macros or conditionals with
     `{$define}' and rely on them being case-sensitive, change it to
     `{$csdefine}' now.

   * The mechanism for including GPC code into code written in other
     languages has changed and is now more robust. A header gpc-in-c.h
     is provided for inclusion of GPC code into C programs, and a demo
     program GPC_C_Pas (together with C code calling it) is supplied to
     demonstrate this. (Including C code into GPC programs works as
     before.)

   * The preprocessor is now called `gpcpp' (it was `gpc-cpp' before).
     If you have installed an older GPC version, please remove gpc-cpp
     now. If you have any scripts that refer to gpc-cpp directly,
     change the reference to gpcpp. If you use DJGPP, and you added the
     GPC specific sections to djgpp.env as described in the FAQ, please
     change `[gpc-cpp]' to `[gpcpp]'.

   * In `--borland-pascal' mode, GPC now ignores everything after
     `end.'. (This also takes care of "^Z" characters at the end of Dos
     text files). In particular, multiple units or modules in one file
     don't work anymore in `--borland-pascal' mode. (B)


File: gpc,  Node: News - Command Line Options and Compiler Directives,  Next: News - Compiler and RTS Built-in Declarations,  Prev: News - General Changes And Possible Incompatibilies with Previous Versions,  Up: News

2.2 Command Line Options and Compiler Directives
================================================

   * `{$ifopt}' works now, with short directives like in BP (`{$ifopt
     X+}') (B) and also with long directives (`{$ifopt
     extended-syntax}')

   * Local compiler directives and defines can be specified with
     `{$local}' and `{$endlocal}'.

   * Delphi (or C++) style `//' comments in default and `--delphi'
     modes, and a switch `--[no-]delphi-comments' to turn them on/off
     explicitly. (D)

   * -W[no-]typed-const (warn about BP style misuse of typed constants)

   * -W[no-]near-far (warn about use of the obsolete BP compatible
     `near' and `far' directives)

   * -W[no-]underscore (warn about double/leading/trailing underscores
     in identifiers)

   * -W[no-]mixed-comments (warn about use of mixed comments)

   * -W[no-]nested-comments (warn about use of nested comments)

   * -W[no-]field-name-problem (don't warn about a problem with field
     names)

   * -W[no-]object-directives (don't warn about unimplemented
     `private', `protected' and `public' directives)

   * -W[no-]warnings (enable/disable warnings)

   * All `-Wfoo' warning options also work as `{$W foo}' compiler
     directives. In contrast to the last alpha release, there must now
     be a space after the `W'. (@)

   * -no-default-paths (disable standard unit etc. paths)

   * -no-unit-path, -no-object-path (disable any unit/object paths
     given so far)

   * -[no-]io-checking (same as `{$I+}', `{$I-}')

   * -[no-]stack-checking, also as compiler directives
     `{$[no-]stack-checking}' or `{$S+}'/`{$S-}' (B)

   * -[no-]typed-address, also as compiler directives
     `{$[no-]typed-address}' or `{$T+}'/`{$T-}' (B)

   * -[no-]transparent-file-names (derive the external file names from
     the file variable names

   * -[no-]progress-messages, -[no-]progress-bar (output information to
     give progress messages or display a progress bar while compiling,
     using suitable utilities)

   * {$[no-]debug-statement[=foo]} (call a procedure automatically
     before each statement for debugging)

   * The `--[no-]c-numbers' switch has been removed. If you really used
     C style octal or hex numbers (`0400', `0xf00'), you can easily
     convert them to the Extended Pascal notation (`8#400', `16#f00')
     or (hex only) to the Borland Pascal notation (`$foo'). (@)

   * `{$gnu-pascal}' is now completely equivalent to `--gnu-pascal';
     `{$gnu-pascal}' has been added to all units shipped with GPC, so
     they can also be compiled when `--borland-pascal' or other dialect
     options are given on the command line.

   * `{$if}' directives now understand Pascal operators like `and',
     `or', `not' (C operators are also still understood).

   * `{$P+}'/`{$P-}' was replaced by `{$[no-]pedantic}' (or
     `--[no-]pedantic' on the command line)

   * The single-letter compiler directives are now BP compatible.
     Those that are not meaningful or not necessary in GPC (e.g.
     `{$F+}', `{$O...}', or `{$M}' with only numbers following) are
     ignored in `--borland-pascal' mode and warned about otherwise. (B)
     Note: `{$W+}'/`{$W-}' is now also ignored in `--borland-pascal'
     mode (it is the only single-letter directive left that has a
     different meaning in BP and in GPC, and besides, the BP meaning
     can be safely ignored in GPC).  To enable/disable warnings in
     `--borland-pascal' mode, you can use `{$W [no-]warnings}' now. (@)

   * The RTS command line options are now also available as long
     options; new RTS options `--version' (print RTS version and exit),
     `--abort-on-error' (abort with SIGABRT on runtime error),
     `--error-file', `--error-fd' (dump runtime error messages and
     strack trace to given file name or FD).

   * RTS command line options are now recognized after `--gpc-rts'
     instead of `-Grts'. Also, a single option can be given with
     `--gpc-rts=OPTION'. This is allowed multiple times. (@)

   * Files with `.pp' or `.dpr' extension are recognized as Pascal
     sources. (D)



File: gpc,  Node: News - Compiler and RTS Built-in Declarations,  Next: News - Units,  Prev: News - Command Line Options and Compiler Directives,  Up: News

2.3 Compiler and RTS Built-in Declarations
==========================================

   Some of the following declarations are built into the compiler,
others are declared in the `GPC' module.

   * Types etc.:

        - ByteBool, ShortBool, WordBool, MedBool, LongBool, LongestBool,
          Boolean(42) (D?)

        - `register' directive

        - Directives with double underscores like `__asmname__',
          `__inline__' have been dropped. The same directives without
          underscores have been available for a long time. Furthermore,
          GPC now supports `^const' to create a pointer to a constant
          (which could be done in a C like fashion with the `__const__'
          directive before). (@)

        - Type qualifiers like `__byte__' or `__unsigned__' have been
          dropped. GPC has been supporting "real" type names like
          `Byte' or `ByteWord' for a long time, and it's easy to change
          to them. Similar for `__cstring__' and `__void__' where
          `CString' and `Void' are available. (@)

   * Expressions:

        - `nil' is accepted as a value of any procedural/functional
          type (B)

        - `shl' and `shr' can also be used as procedures now.

        - `mod' with negative right operand now works like in BP.  (B)

        - Expressions like `-2 * +3' are now allowed without
          parentheses. (B)

   * Files and I/O:

        - SeekEOF, SeekEOLn (B)

        - IOErrorFile

        - New parameter `ElementSize' to ReverseBytes,
          ConvertFromLittleEndian, ConvertFromBigEndian,
          ConvertToLittleEndian, ConvertToBigEndian,
          BlockReadLittleEndian, BlockReadBigEndian,
          BlockWriteLittleEndian, BlockWriteBigEndian (@)

        - ReadStringLittleEndian

        - ReadStringBigEndian

        - WriteStringLittleEndian

        - WriteStringBigEndian

        - GetTempFileNameInDirectory

        - PathExists

        - DataDirectoryName

        - AssignBinary

        - HasWildCardsOrBraces

        - BraceExpand

        - MultiFileNameMatch

        - GlobOn

        - MultiGlob

        - MultiGlobOn

        - QuoteFileName

        - UnQuoteFileName

        - FExpandQuoted

        - ForceAddDirSeparator

        - FindNonQuotedChar

        - FindNonQuotedStr

        - NameExtFromPath

        - SystemInfo

        - GetMountPoint

        - FileMove

        - ChMod

        - IOSelect

        - IOSelectRead

        - FileNameLoCase

        - FileNamesCaseSensitive (constant)

        - DirRoot (constant)

        - MaskNoStdDir (constant)

        - QuotingCharacter (constant)

        - EnvVarChars (constant)

        - EnvVarCharsFirst (constant)

        - WildCardChars (constant)

        - FileNameSpecialChars (constant)

        - ShellExecCommand (constant)

        - DataReady renamed to CanRead (@)

        - FileLock, FileUnlock

        - MemoryMap, MemoryUnMap

        - New parameter `Quoted' to RelativePath (@)

        - New parameter `Prefix' to ConfigFileName (@)

        - New parameter `AccessTime' to SetFileName (@)

        - ExpandEnvironment recognizes `~user'

        - Each of the parameters `Dir', `Name' and `Ext' to `FSplit'
          may now be null.

        - New fields `User', `Group', `Mode', `Device', `INode',
          `SymLink', `TextBinary' and `Special' in BindingType

        - The variable `TextFilesBinary' has been dropped. Instead, you
          can now use the procedure `AssignBinary' or the field
          `TextBinary' in BindingType. (@)

        - File sizes can now be bigger than `Integer' (e.g. 64 bit
          files on 32 bit machines) if supported by the OS via
          lseek64() or llseek() (e.g. Linux, Solaris, IRIX).

        - Renamed the file mode constants from `fmFOO' to `fm_FOO'. (@)

        - `GetIOErrorMessage' now returns a string rather than a
          `CString'. (@)

        - In `GlobBuffer', the fields `Count' and `Result' (pointer to
          an array of `CString's, 0 baser) were replaced by `Result', a
          pointer to an array of pointers to strings, 1 based). (@)

   * Strings:

        - Integer2String

        - IsUpCase

        - IsLoCase

        - IsAlphaNum

        - IsAlphaNumUnderscore

        - IsPrintable

        - Renamed the CString routines in the RTS so they get a
          `CString' prefix, moved the BP compatibility identifiers for
          the same routines into the `Strings' unit (B) (@)

        - MemCompCase

        - StrEqualCase

        - PosCase

        - LastPosCase

        - PosFromCase

        - LastPosTillCase

        - IsPrefixCase

        - IsSuffixCase

        - LineBreak (constant)

        - SetEnv (makes obsolete libc's PutEnv (@))

        - UnSetEnv

        - GetCEnvironment

        - DisposePPStrings

        - The environment variable management is now implemented in
          Pascal, so it's independent of libc differences (e.g. the
          presence or not of `environ'). Access via `GetEnv' etc. works
          unchanged.

        - The `Environment' variable is now a schema which contains the
          environment variables as CStrings. (@)

        - Empty and case-sensitive environment variables are allowed
          within GPC programs even under Dos.

   * Random:

        - SeedRandom

        - SeedRandomPtr (variable)

        - Randomize is called automatically when necessary (except when
          using the BP compatible random number generator in the System
          unit (B)).

   * Memory:

        - ReAlloc; previous ReAlloc function (libc) renamed to CReAlloc
          (@)

        - ReAllocPtr (variable)

        - ReleaseCount

        - AllocateBigMem, DisposeBigMem, MoveToBigMem, MoveFromBigMem,
          MapBigMem for uniform access to big memory blocks for GPC and
          BP (B)

   * Time:

        - Sleep

        - SleepMicroSeconds

        - Alarm

        - GetCPUTime

        - GetMicroSecondTime

        - FormatTime

        - The constant `MonthLength' was replaced by a function of the
          same name that handles leap years. (@)

        - DayOfWeekName (constant)

        - InvalidYear (constant)

   * Misc:

        - Include and Exclude for sets (B)

        - IsInfinity

        - IsNotANumber

        - SplitReal

        - ReturnAddress

        - FrameAddress

        - Runtime errors are now printed with their address to help
          debugging (using addr2line), and the address is stored in
          ErrorAddr. (B)

        - RegisterRestoreTerminal

        - UnregisterRestoreTerminal

        - RestoreTerminal

        - ExecuteNoTerminal

        - SetProcessGroup

        - SetTerminalProcessGroup

        - GetTerminalProcessGroup

        - GetTerminalName

        - SetInputSignals

        - GetInputSignals

        - GetShellPath

        - GetPasswordEntryByName

        - GetPasswordEntryByUID

        - GetPasswordEntries

        - StrSignal

        - Kill

        - WaitPID

        - InstallSignalHandler

        - BlockSignal

        - SignalBlocked

        - Constants for the signals

        - UserID

        - GroupID

        - IllReservedAddress, IllPriviledgedInstruction, IllReservedOp
          were removed. (@)



File: gpc,  Node: News - Units,  Next: News - GPC Manual,  Prev: News - Compiler and RTS Built-in Declarations,  Up: News

2.4 GPC Units
=============

   * CRT:

        - Works now under Cygwin and mingw.

        - DJGPP: support for 40 column modes (requires updated PDCurses
          library)

        - Renamed the the conditional to get an X11 version from
          XCURSES to X11. (@)

        - Renamed GetScreenSize to ScreenSize (WinCRT compatibility)
          (B) (@)

        - WindowOrg, WindowSize, Cursor, Origin, InactiveTitle,
          AutoTracking, WindowTitle, (variables), ScrollTo, TrackCursor
          (WinCRT compatibility) (B)

        - SimulateBlockCursor, SimulateBlockCursorOff

        - Curses is not initialized at the beginning of the program, but
          rather when the first CRT routine is called. (B)

        - CRTInit to explicitly initialize CRT and also set some
          defaults (PCCharSet and update level) to more natural (and
          less BP compatible) values.

        - CRTSetTerminal

        - CRTAutoInitProc (variable)

        - CRTNotInitialized

        - CRTSavePreviousScreen

        - CRTSavePreviousScreenWorks

        - Any of the parameters to GetWindow may now be null.

        - Support for panels (overlapping windows): GetActivePanel,
          PanelNew, PanelDelete, PanelBindToBackground,
          PanelIsBoundToBackground, PanelActivate, PanelHide, PanelShow,
          PanelHidden, PanelTop, PanelBottom, PanelMoveAbove,
          PanelMoveBelow, PanelAbove, PanelBelow, IgnoreCursor

        - Replaced the variables PCCharSet and UseControlChars by
          routines SetPCCharSet, GetPCCharSet, SetControlChars,
          GetControlChars. (@)

        - SetScreenSize

        - SetMonochrome

        - Renamed IsMonoMode to IsMonochrome. (@)

        - On ncurses platforms, changing the screen is now done through
          a shell command definable in the environment variable
          `RESIZETERM' (which defaults to `resize', `SVGATextMode' and
          `setfont'). The variables `crt_setfont_command_80_25',
          `crt_setfont_command_80_50', `crt_setfont_command_40_25' and
          `crt_setfont_command_40_50' (Linux only) were removed. (@)

        - CRTUpdate

        - CRTRedraw

        - SetScroll

        - CRTSetCursesMode

        - RestoreTerminalClearCRT

        - CtrlKey

        - AltKey

        - AltGrKey

        - ExtraKey

        - constants chCtrlA ... chCtrlZ, kbCtrlA ... kbCtrlZ

        - Catch some signals and return pseudo function keys for them if
          CheckBreak is False.

        - React to screen size changes by external events and return a
          pseudo function key.

        - Reduced the (already small) system-dependent code, and added
          an overview of the few problematic features in the comment at
          the beginning of crt.pas.

   * RegEx:

        - RegExPosFrom

        - CharSet2RegEx

        - Support for converting subexpression or complete matching
          references to upper or lower case while replacing them with
          `\u7' or `\l7'.

   * GMP:

        - mpf_exp

        - mpf_ln

        - mpf_pow

        - mpf_arctan

        - mpf_pi

        - The unit now works with version 3.x of the GMP library, but it
          also still works with version 2.x.

   * System:

        - SetTextBuf (B)

        - RealToBPReal, BPRealToReal to convert between binary BP
          compatible 6 byte reals and GPC's reals (useful, e.g., for
          binary file exchange with BP programs) (B)

        - Ofs, Seg, Ptr, CSeg, DSeg, SSeg, SPtr (mostly useless and only
          for BP compatibility) (B)

        - A number of variables like SelectorInc (mostly useless and
          only for BP compatibility) (B)

        - Renamed the `__BP_INTEGERS__' conditional to
          `__BP_TYPE_SIZES__'. (@)

   * Dos, WinDos:

        - GetCBreak

        - SetCBreak

        - GetVerify

        - SetVerify

        - Renamed the `_Borland_16_Bit_' conditional to
          `__BP_TYPE_SIZES__'. (@)

        - Intr, MsDos, only under DJGPP if `__BP_UNPORTABLE_ROUTINES__'
          is defined. (B)

        - DosVersion, SetDate, SetTime, only if
          `__BP_UNPORTABLE_ROUTINES__' is defined (emulated on
          non-DJGPP). (B)

   * RegEx:

        - In `RegExType', the field `Error' is now of type `PString'
          rather than `CString'. (@)

   * Pipe:

        - New parameter `Process' to Pipe (@)

        - WaitPipeProcess

   * PExecute:

        - Integrated into the RTS so you don't need a `uses PExecute'
          anymore. (@)

   * GetOpt:

        - ResetGetOpt

        - `GetOptErrorFlag' is now True by default. (@)

        - Integrated into the RTS so you don't need a `uses GetOpt'
          anymore. (@)

        - Renamed the variables and constants used (see gpc.pas under
          `Command Line Option Parsing'). (@)

        - `GetOptLong' can now optionally derive the short options from
          the `LongOptions' array.

   * WinCRT:

     New unit (identical to CRT) (B)

   * HeapMon:

     New unit for (simple) heap checking.

   * Trap:

     New unit for runtime error trapping.

   * MD5:

     New unit for computing MD5 message digests.

   * FileUtils:

     New unit with some file and directory utilities.

   * StringUtils:

     New unit with some string utilities.

   * GPC-BP:

     A `GPC' unit for BP to provide some GPC compatibility to BP
     programs and make it easier to gradually convert them to GPC. (G)


   A few of the units (in particular: CRT, GMP and RegEx) require
libraries. The sources of the libraries, with small patches where
necessary, as well as binaries for i586-pc-linux-gnu,
i586-pc-linux-gnulibc1, m68k-linux, sparc-sun-solaris2, i386-pc-go32,
i386-pc-cygwin32 and i386-pc-mingw32 are available from
     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/'


File: gpc,  Node: News - GPC Manual,  Next: News - Demo Programs,  Prev: News - Units,  Up: News

2.5 GPC Manual
==============

   * Some very obsolete sections of the manual (e.g., the output of
     running the PVS test suite on an Alpha machine in 1995 ;-) were
     removed.

   * The manual was restructured. Several partly overlapping chapters
     were included into the Programmer's Guide, and the overlapping
     material was merged into more coherent sections.

   * The BP QuickStart Guide was left a separate chapter and completed
     with a section about differences between BP and GPC, especially
     mentioning endianness issues.

   * A lot of new material was added to the `Programming' and
     `Reference' chapters.

   * The list of command-line options and the list of keywords for the
     various dialects were updated, and from now on, they are
     automatically kept up to date, directly from the source. The
     `Invoking GPC' chapter does not contain all options inherited from
     GCC anymore (these can be found in the GCC manual, anyway), but
     rather more extensive descriptions of the most commonly used GPC
     options, with examples.

   * The interface of all units included with GPC, together with a
     short description of the units, is now included in the manual. The
     interface, also that of the `GPC' module which describes the
     interface to the Run Time System, is formatted more nicely,
     especially in the printed version of the manual.

   * The `Support' chapter was updated, now including information about
     GPC's Test Suite and how to report bugs most effectively, as well
     as up-to-date contact information.

   * The installation instructions were updated, now matching the
     current GPC and GCC versions.

   * The FAQ, the To-Do list, and the list of new features (this one
     :-) were integrated into the manual.

   * The list of authors in the manual was updated, and the list of
     contributors was included from the WWW page.

   * The manual was integrated with GPC's WWW pages, i.e. most of the
     WWW pages were synchronized with the corresponding information in
     the manual, and both now contain the same information.



File: gpc,  Node: News - Demo Programs,  Next: News - Test Suite,  Prev: News - GPC Manual,  Up: News

2.6 Demo Programs
=================

   * There is a number of new demo programs to demonstrate some
     features of the compiler and the units. The demo programs are part
     of source and binary GPC distributions. After installation, they
     can be found in `<prefix>/doc/gpc/demos/'.

   * The demo programs printed in the GPC Manual (currently 186, but
     expected to become more) are now installed as separate files,
     ready to be compiled, in a directory `<prefix>/doc/gpc/docdemos/'.



File: gpc,  Node: News - Test Suite,  Next: Legend,  Prev: News - Demo Programs,  Up: News

2.7 Test Suite
==============

   The Test Suite is used to verify that all features of GPC work as
expected and to reproduce bugs reported. Test programs for bugs found
by users and for new features are constantly added. The test suite is
part of source, not binary, GPC distributions.

   * As usual, many new tests have been added to the Test Suite.

   * The few checks dependent on the system or certain installed tools
     or libraries have been equipped with checks about the system
     properties, and are skipped on systems on which they are not
     applicable.

   * The old dejagnu tests have been integrated into the Test Suite.

   * `pascal.check' (or `check-pascal') now runs the current Test Suite
     (as `make check2-gpc' did before) rather than the (now removed)
     dejagnu tests. This must be done in the build directory (not the
     `p' subdirectory) or in the `test' subdirectory of the source
     directory. (@)

   * The Test Suite now produces a summary output by default. To get
     the long output format as before, run `make pascal.check-long' (or
     `check-pascal-long') now.

   * The GPC Manual as well as the `test/README' file in source
     distributions (or `BUGS' in binary distributions) tells you how to
     run the Test Suite and describes all features of the testing
     environment, to make it easier for users to construct even exotic
     new tests, and contains some generic instructions on how to report
     bugs.  See *Note Testing::, and see *Note Reporting Bugs::.


File: gpc,  Node: Legend,  Prev: News - Test Suite,  Up: News

2.8 Legend
==========

`(@)':   minor backward-incompatibility
`(B)':   BP compatibility
`(D)':   Delphi compatibility
`(G)':   GPC compatibility :-)

   Have fun,

   The GNU Pascal Development Team


File: gpc,  Node: FAQ,  Next: Installation,  Prev: News,  Up: Top

3 The GNU Pascal Frequently Asked Questions List.
*************************************************

Edition 0.9, August 2000
------------------------

   This is the Frequently Asked Questions List (FAQ) for GNU Pascal. If
the FAQ and the documentation do not help you, you have detected a
*bug* in it which should be reported, *Note Mailing List::.  Please
really do it, so we can improve the documentation.

* Menu:

* GNU Pascal::          GNU Pascal
* Installing GPC::      Installing GPC
* GPC on DJGPP::        GNU Pascal on the DJGPP (MS-DOS) platform
* Strings in GPC::      Strings
* Getting Help::        Getting Help
* Miscellaneous FAQ::   Miscellaneous


File: gpc,  Node: GNU Pascal,  Next: Installing GPC,  Up: FAQ

3.1 GNU Pascal
==============

* Menu:

* What and why::                What and why?
* Current version::             What is the current version?
* Turbo Pascal compatibility::  Is it compatible with Turbo Pascal (R)?
* Supported platforms::         Which platforms are supported by GNU Pascal?


File: gpc,  Node: What and why,  Next: Current version,  Up: GNU Pascal

3.1.1 What and why?
-------------------

   The purpose of the GNU Pascal project is to produce a Pascal
compiler (called GNU Pascal or GPC) which

   * combines the clarity of Pascal with powerful tools suitable for
     real-life programming,

   * supports both the Pascal standard and the Extended Pascal standard
     as defined by ISO, ANSI and IEEE (ISO 7185:1990, ISO/IEC
     10206:1991, ANSI/IEEE 770X3.160-1989),

   * supports other Pascal standards (UCSD Pascal, Borland Pascal,
     Pascal-SC) in so far as this serves the goal of clarity and
     usability,

   * may be distributed under GNU license conditions, and

   * can generate code for and run on any computer for which the GNU C
     compiler can generate code and run on.

   Pascal was originally designed for teaching. GNU Pascal provides a
smooth way to proceed to challenging programming tasks without learning
a completely different language.

   The current release implements Standard Pascal (ISO 7185, level 1),
a large subset of Extended Pascal (ISO 10206, aiming for full
compliance), is highly compatible to Borland Pascal (version 7.0) with
some Delphi extensions, and provides a lot of useful GNU extensions.


File: gpc,  Node: Current version,  Next: Turbo Pascal compatibility,  Prev: What and why,  Up: GNU Pascal

3.1.2 What is the current version?
----------------------------------

   Prior to July 2000 releases were several months apart. Since then
there has been a new release every few days, available as a source
archive or from a CVS server from the GPC web site,
`http://home.pages.de/~GNU-Pascal/'.

   For details about new features, see the section `News' on the web
site. On bugs fixed recently, see the `Done' section of the To-Do list
(on the same web site).

   GPC uses GCC as a back-end. Patches for GCC 2.8.1 and GCC 2.95.x are
provided but it is recommended that you use GCC 2.95.x.


File: gpc,  Node: Turbo Pascal compatibility,  Next: Supported platforms,  Prev: Current version,  Up: GNU Pascal

3.1.3 Is it compatible with Turbo Pascal (R)?
---------------------------------------------

   GPC is not a drop-in replacement for Borland's Turbo Pascal (R).
Almost all BP language features are supported. Notable exceptions are
the string format (as discussed below), or the `Mem' and `Port' pseudo
arrays, though replacement functions for the latter on x86 platforms
exist in the `Ports' unit.

   Almost all of BP's run time library is supported in GPC, either by
built-in compiler features or in units with the same names as their BP
counterparts.

   For details about the compatibility, the few remaining
incompatibilities and some useful alternatives to BP features, see the
`Borland Pascal' chapter in the GPC Manual.  (*note Borland Pascal::)


File: gpc,  Node: Supported platforms,  Prev: Turbo Pascal compatibility,  Up: GNU Pascal

3.1.4 Which platforms are supported by GNU Pascal?
--------------------------------------------------

   GPC uses the GCC backend, so it should run on any system that is
supported by GNU CC. This includes a large variety of Unix systems,
MS-DOS, OS/2 and Win32. A full list of platforms supported by GCC can
be found in the file `INSTALL' of the GCC distribution. Not all of
these have actually been tested, but it is known to run on these
platforms:

ix86-linux                    (Linux 2.x, ELF)
i486-linuxaout                
i486-linuxoldld               
i386-freebsd1.2.0             
AIX 4.2.1                     
AIX 4.3                       
DJGPP V2                      (Dos)
EMX 0.9B                      (OS/2, Dos)
Cygwin32 beta20 and higher    (MS-Windows95/98, MS-Windows NT)
Mingw32                       (MS-Windows95/98, MS-Windows NT)
mips-sgi-irix5.3              
sun-sparc-sunos4.1.4          
sparc-sun-solaris2.x          
sun-sparc-solaris 2.5.1       
sun-sparc-solaris 2.6         
sun-sparc-solaris 7           
alpha-unknown-linux           
alphaev56-dec-osf4.0d         

   *OK people - send us your success stories, with canonical machine
name!*


File: gpc,  Node: Installing GPC,  Next: GPC on DJGPP,  Prev: GNU Pascal,  Up: FAQ

3.2 Installing GPC
==================

   You find the most up-to-date installation instructions in the GPC
Manual or the file `INSTALL' in source distributions, or on the GPC web
site.  (*note Installation::)

   The following sections describe things you might need or want to
install besides GPC itself.

* Menu:

* Documentation files::  What to read next
* Components::           Which components do I need to compile Pascal code?
* Debugger::             How do I debug my Pascal programs?
* Libraries::            What additional libraries should I have?
* Contributed units::    Contributed units
* IDE::                  Can you recommend an IDE?


File: gpc,  Node: Documentation files,  Next: Components,  Up: Installing GPC

3.2.1 What to read next
-----------------------

   After installing GPC, please check the files in the directory
`/usr/local/doc/gpc':

`README'       General Information about GPC
`FAQ'          This FAQ :-)
`NEWS'         Changes since the last release
`LIBS'         Libraries used by some GPC units
`BUGS'         How to report bugs, about the Test Suite
`AUTHORS'      List of GPC authors
`COPYING'      The GNU General Public License


File: gpc,  Node: Components,  Next: Debugger,  Prev: Documentation files,  Up: Installing GPC

3.2.2 Which components do I need to compile Pascal code?
--------------------------------------------------------

   A complete Pascal compiler system should at least have:

  1. The actual compiler, GPC.

  2. An editor, assembler, linker, librarian and friends.

  3. A C library. If you have a working C compiler, you already have
     this.

  4. A debugger, if you want to debug your programs.

   For most people, the GNU binutils and GNU debugger (`gdb') are a
good choice, although some may prefer to use vendor specific tools.


File: gpc,  Node: Debugger,  Next: Libraries,  Prev: Components,  Up: Installing GPC

3.2.3 How do I debug my Pascal programs?
----------------------------------------

   To debug your programs, (a) GNU Pascal must be able to generate
executables with debug info for your platform, and (b) you must have a
debugger which understands this.

   * If `gpc -g -o hello hello.p' says:
          gpc: -g not supported for this platform
     then GPC is unable to generate debugging info. Usually, installing
     `gas' (part of GNU binutils) instead of your system's assembler
     can overcome this. When you configure the GCC used for GPC, specify
     `--with-gnu-as', and possibly `--with-gnu-ld' and/or
     `--with-stabs'. More information can be found in the `INSTALL'
     file in the GNU CC source directory.

   * Your system's debugger may not understand the debug info generated
     by GNU tools. In this case, installing `gdb' may help.

   The bottom line: if you can debug GCC compiled programs, you should
be able to do this with GPC too.

   The GNU debugger (`gdb') currently does not have a "Pascal" mode, so
it is unable to display certain Pascal structures etc. When debugging,
please note that the Initial Letter In Each Identifier Is In Upper Case
And The Rest Are In Lower Case. If you want to display variable `foo'
in the debugger, type `show Foo' or `display Foo' instead.

   Although `gdb' is an excellent debugger, it's user interface is not
everybody's preference. If you like to debug under X11, please refer to
the comp.windows.x FAQ: "Where can I get an X-based debugger?" at:
`http://www.cis.ohio-state.edu/hypertext/faq/usenet/x-faq/part6/faq-doc-2.html'

   Some useful frontends include: XXGDB, tGDB and XWPE. See:
`http://www.ee.ryerson.ca:8080/~elf/xapps/Q-IV.html'

   Very nice, but resource consuming is the Motif based DDD:
`http://sol.ibr.cs.tu-bs.de/softech/ddd/'

   Furthermore, RHIDE (*note IDE::) contains built-in debugging suport,
similar to the IDE of BP.


File: gpc,  Node: Libraries,  Next: Contributed units,  Prev: Debugger,  Up: Installing GPC

3.2.4 What additional libraries should I have?
----------------------------------------------

   You will need certain additional libraries when you compile some of
the units. These can be found in the directory
`ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/'.

   Currently, there are the following libraries:

gmp
     Arithmetic for integers, rationals and real numbers with arbitrary
     size and precision. Used by the GMP unit.

rx
     Regular expression matching and substitution. Used by the RegEx
     unit.

ncurses
PDCurses
     Screen handling. Used by the CRT unit. Depending on your system,
     you have the following choices:

     Unix: You can compile terminal applications with ncurses and
     applications that run in an X11 window with PDCurses (though
     terminal applications can, of course, also run in an xterm under
     X11). ncurses is used by default. If you want to use PDCurses
     (a.k.a. XCurses), give the option `-DX11' when compiling CRT.

     Dos with DJGPP and MS-Windows with mingw: Only PDCurses is
     available and will be used by default.

     MS-Windows with Cygwin: PDCurses and ncurses are available.
     PDCurses is used by default. If you want to use ncurses, give the
     option `-DUSE_NCURSES' when compiling CRT.

     Other systems: Please see the `README's and installation
     instructions of PDCurses and ncurses to find out which one(s) can
     be built on your system. See the conditionals at the end of
     crt.inc and crtc.h (and change them if necessary) on which library
     is used by default.

ElectricFence
     This library is not used by any GPC unit. It is a debugging tool to
     assist you in finding memory allocation bugs. To use it, just link
     it to your program, either on the command line (`-lefence') or in
     the source code (`{$L efence}') which you might want to put into
     an `{$ifdef DEBUG}' or similar since using libefence is only
     recommended for debugging.

   The source code of the libraries is available in the main `libs'
directory. Most libraries come with one or several patches which should
be applied before compiling them.

   Binaries for some platforms are available in the `binary/PLATFORM'
subdirectories. If you compile the libraries for other platforms, be
invited to make the binaries available to us for distribution on the
FTP site.

   There are also the following files:

`terminfo-linux.tar.gz'
     This is a patch to enable ncurses programs to make use of the
     ability of Linux 2.2 and newer kernels to produce a block cursor
     when needed. The present patch can be installed without recompiling
     anything, just by copying some files into place. More details can
     be found in the `README' file included in this archive. The patch
     will not do any harm on older kernels. Please note that *not* only
     on Linux machines it is useful to install the patch. Installing
     them on any other machine will allow users who telnet in from a
     Linux console to profit from the block cursor capability. Besides,
     some Unix systems have installed older Linux terminfo entries or
     none at all, so it's a good thing, anyway, to give them a current
     version. The patch is included in the terminfo database of ncurses
     5.0, so if you install ncurses 5.0 (source or binary), you don't
     need to get the patch separately. But you can install it on a
     system with an older ncurses version if you don't feel like
     upgrading ncurses altogether.

`tsort-2.9i.zip'
     A little utility (extracted from util-linux-2.9i, but not Linux
     specific), needed for the configuration of the rx library. You
     need it only if you compile rx yourself (and if it's not already
     present on your system), not when using a rx binary.


File: gpc,  Node: Contributed units,  Next: IDE,  Prev: Libraries,  Up: Installing GPC

3.2.5 Contributed units
-----------------------

   Several people have contributed units for GPC. They are usually
announced on the mailing list, *Note Mailing List::. Here's a selection:

   * Nicola Girardi wrote a unit which you can use to interface Svgalib.
     You can read a mini-FAQ about it at
     `http://ages.dida.physik.uni-essen.de/~nicola/', complete with
     links to download the unit via http or ftp. If you want to download
     the unit directly, get `svgalib-gpc-20000216.tar.gz' from
     `ftp://agnes.dida.physik.uni-essen.de/home/nicola/'.

   * Prof. Abimbola A. Olowofoyeku ("The African Chief") wrote a
     Delphi-compatible (though a few routines are still missing)
     `SysUtils' unit. It has been tested under Cygwin, Mingw, Linux
     (Mandrake 7.0), and Solaris 7. It can be downloaded from
     `ftp://agnes.dida.physik.uni-essen.de/home/chief/sysutils-20000725.zip'.

   * Eike Lange wrote units to access MySql, GNU DBM and PostgreSQL data
     bases. As of this writing (Aug 2000), they are in Alpha stage. They
     can be downloaded from
     `ftp://agnes.dida.physik.uni-essen.de/home/lange/'.


File: gpc,  Node: IDE,  Prev: Contributed units,  Up: Installing GPC

3.2.6 Can you recommend an IDE?
-------------------------------

   Users of Borland Pascal may wonder if there's a replacement for the
IDE (Integrated Development Environment). Here's a few suggestions:

   * (X)Emacs. Some people think it's the answer to the question of
     Life, the Universe and Everything, others decide it's uGNUsable.
     Available from your friendly GNU mirror and most distributions.

   * RHIDE. DJGPP users might want to try RHIDE. The latest (beta)
     release is compatible with GNU Pascal and allows stepping, tracing
     and watching like Borland's IDE. It can be downloaded from
     `http://www.tu-chemnitz.de/~sho/rho/rhide/rhide.html'.

   * PENG. It's not free software, but it was written with GPC.  It's
     very similar to Borland's IDE, but with many extensions.  Binaries
     for DJGPP, Linux and Solaris can be downloaded from
     `http://fjf.gnu.de/peng.html'.

   * XWPE is another imitation of the Borland IDE, so users of Borland
     Pascal may find it a good alternative.


File: gpc,  Node: GPC on DJGPP,  Next: Strings in GPC,  Prev: Installing GPC,  Up: FAQ

3.3 GNU Pascal on the DJGPP (MS-DOS) platform
=============================================

   This chapter discusses some potential problems with GNU Pascal on
MS-DOS, using DJGPP.

* Menu:

* What is DJGPP::            What is DJGPP?
* DJGPP FAQ::                If you need more information
* DJGPP download::           What do I download?
* Installing GPC on DJGPP::  How do I install the compiler?
* DJGPP Info reader::        I cannot read the Info documentation!
* DJGPP DPMI server::        GPC says: no DPMI
* Assembler syntax::         I have troubles with assembly code
* DJGPP specific code::      Tell me how to do DPMI, BIOS and
                             other DOS related things.
* DJGPP stack size::         I got an exception when accessing an
                             `array [1 .. 4000000] of Byte'.


File: gpc,  Node: What is DJGPP,  Next: DJGPP FAQ,  Up: GPC on DJGPP

3.3.1 What is DJGPP?
--------------------

   The following paragraph is from the site
`http://www.delorie.com/djgpp/':

   DJGPP is a complete 32-bit C/C++ development system for Intel 80386
(and higher) PCs running DOS. It includes ports of many GNU development
utilities. The development tools require a 80386 or newer computer to
run, as do the programs they produce. In most cases, the programs it
produces can be sold commercially without license or royalties.


File: gpc,  Node: DJGPP FAQ,  Next: DJGPP download,  Prev: What is DJGPP,  Up: GPC on DJGPP

3.3.2 If you need more information
----------------------------------

   GPC/DJGPP is a DJGPP V2 application, and most of the DJGPP
documentation applies for GPC too. A great source of information is the
DJGPP FAQ: `http://www.delorie.com/djgpp/v2faq/230b.zip'

   Another place to look for DJGPP documentation is the DJGPP Knowledge
Base, at this URL: `http://www.delorie.com/djgpp/doc/kb/'


File: gpc,  Node: DJGPP download,  Next: Installing GPC on DJGPP,  Prev: DJGPP FAQ,  Up: GPC on DJGPP

3.3.3 What do I download?
-------------------------

   As discussed in *Note Components::, other than GPC itself, you need
an assembler, linker and friends, a C library and possibly a debugger.
The site `http://www.delorie.com/djgpp/' recommended the following
files and they will help you find a mirror:

`v2/djdev203.zip'       (C library)
`v2gnu/bnu2951b.zip'    (assembler, ....)
`v2gnu/gcc2952b.zip'    (gcc)
`v2gnu/gdb418b.zip'     (debugger)
`v2gnu/mak379b.zip'     (make)
`v2gnu/txi40b.zip'      (texi)

   This list is about 10 MB not counting GPC. You can use a binary
version of GPC from agnes.


File: gpc,  Node: Installing GPC on DJGPP,  Next: DJGPP Info reader,  Prev: DJGPP download,  Up: GPC on DJGPP

3.3.4 How do I install the compiler?
------------------------------------

   If you don't have DJGPP installed on your harddisk, create a
directory for GNU Pascal (`c:\gpc'), and unzip the archives.  Make sure
you preserve the directory structure (use `pkunzip -d'). Now, add the
directory where `gpc.exe' lives (`c:\gpc\bin') to your path and set the
DJGPP environment variable to point to your `djgpp.env' file:

     set DJGPP=c:\gpc\djgpp.env

   Then, add this to your `djgpp.env' file:

     ---------------------------------------------------------
     [gpcpp]
     C_INCLUDE_PATH=%/>;C_INCLUDE_PATH%%DJDIR%/lang/pascal;%DJDIR%/include
     
     [gpc]
     COMPILER_PATH=%/>;COMPILER_PATH%%DJDIR%/bin
     LIBRARY_PATH=%/>;LIBRARY_PATH%%DJDIR%/lib;%DJDIR%/contrib/grx20/lib
     ---------------------------------------------------------

   The binary distribution should come with a `djgpp.env' which is
already modified, so you may not have to do this.

   The GPC online documentation is in GNU info format; you need the
Info reader (`txi390b.zip') to read it, or use the built-in Info reader
of the RHIDE or PENG IDE. To add the GPC documentation to the info
directory file, edit the `c:\gpc\info\dir' file, and locate this
section:

     ---------------------------------------------------------
     * GCC: (gcc.inf).
     The GNU C, C++, and Objective-C Compiler
     
     * GDB: (gdb.inf).
     The GNU Debugger (gdb and gdb-dpmi).
     
     ---------------------------------------------------------

   To add GPC, change it to look like this:

     ---------------------------------------------------------
     * GCC: (gcc.inf).
     The GNU C, C++, and Objective-C Compiler
     
     * GPC: (gpc.inf).
     The GNU Pascal Compiler
     
     * GDB: (gdb.inf).
     The GNU Debugger (gdb and gdb-dpmi).
     
     ---------------------------------------------------------

   Specific information for low-memory conditions and more can be found
in the DJGPP FAQ and documentation.


File: gpc,  Node: DJGPP Info reader,  Next: DJGPP DPMI server,  Prev: Installing GPC on DJGPP,  Up: GPC on DJGPP

3.3.5 I cannot read the Info documentation!
-------------------------------------------

   To read the Info documentation, you need the `info' program from
`txi390b.zip' or an IDE like RHIDE or PENG.


File: gpc,  Node: DJGPP DPMI server,  Next: Assembler syntax,  Prev: DJGPP Info reader,  Up: GPC on DJGPP

3.3.6 GPC says: no DPMI
-----------------------

   You don't have a DPMI server installed, and DJGPP v2 requires it to
run. You can either use one of the commercial DPMI servers (e.g., run
`gpc' in a DOS box under MS-Windows) or download and install CWSDPMI
(`csdpmi3b.zip') which is a free DPMI server written for DJGPP.


File: gpc,  Node: Assembler syntax,  Next: DJGPP specific code,  Prev: DJGPP DPMI server,  Up: GPC on DJGPP

3.3.7 I have troubles with assembly code
----------------------------------------

   The GNU Assembler (`as.exe'), or `gas', called by GCC accepts "AT&T"
syntax which is different from "Intel" syntax.  Differences are
discussed in section 17.1 of the DJGPP FAQ.

   A guide is available which was written by Brennan Mr. Wacko
Underwood <brennan@mack.rt66.com> and describes how to use inline
assembly programming with DJGPP, at this URL:
`http://www.rt66.com/~brennan/djgpp/djgpp_asm.html'

   There's also a GPC assembler tutorial at
`ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/contrib/gpcasm.zip'

   Section 17.3 of the DJGPP FAQ discusses some methods to convert
"Intel" syntax to "AT&T" syntax.


File: gpc,  Node: DJGPP specific code,  Next: DJGPP stack size,  Prev: Assembler syntax,  Up: GPC on DJGPP

3.3.8 Tell me how to do DPMI, BIOS and other DOS related things.
----------------------------------------------------------------

   DPMI, BIOS and other functions are no different than other system
functions. Refer to the GPC Manual on how to access your system's
C-library. This small example shows how to use DPMI, copying some
structures and function prototypes of `<dpmi.h>':

     program DPMIDemo;
     
     { Only for DJGPP }
     
     {$X+}
     
     { `Byte' is `unsigned char' in C,
       `ShortCard' is `unsigned short' in C,
       `MedCard' is `unsigned long' in C,
       `Word' is `unsigned' in C,
       etc. (all these types are built-in). }
     
     type
       TDpmiVersionRet = record
         Major      : Byte;
         Minor      : Byte;
         Flags      : ShortCard;
         CPU        : Byte;
         Master_PIC : Byte;
         Slave_PIC  : Byte;
       end;
     
     type
       TDpmiFreeMemInfo = record
         Largest_Available_Free_Block_In_Bytes,
         Maximum_Unlocked_Page_Allocation_In_Pages,
         Maximum_Locked_Page_Allocation_In_Pages,
         Linear_Address_Space_Size_In_Pages,
         Total_Number_Of_Unlocked_Pages,
         Total_Number_Of_Free_Pages,
         Total_Number_Of_Physical_Pages,
         Free_Linear_Address_Space_In_Pages,
         Size_Of_Paging_File_Partition_In_Pages,
         Reserved1,
         Reserved2,
         Reserved3 : MedCard;
       end;
     
     function DpmiGetVersion (var Version: TDpmiVersionRet): Integer;
              asmname '__dpmi_get_version';
     
     function DpmiGetFreeMemoryInformation
              (var MemInfo: TDpmiFreeMemInfo): Integer;
              asmname '__dpmi_get_free_memory_information';
     
     var
       Version: TDpmiVersionRet;
       MemInfo: TDpmiFreeMemInfo;
     
     begin
       if DpmiGetVersion (Version) = 0 then
         begin
           WriteLn ('CPU type :       ', Version.cpu, '86');
           WriteLn ('DPMI major :       ', Version.Major);
           WriteLn ('DPMI minor :       ', Version.Minor);
         end
       else
         WriteLn ('Error in DpmiGetVersion');
       if DpmiGetFreeMemoryInformation (MemInfo) = 0 then
         WriteLn ('Free DPMI memory : ',
                  MemInfo.Total_Number_Of_Free_Pages, ' pages.')
       else
         WriteLn ('Error in DpmiGetMemoryInformation');
     end.


File: gpc,  Node: DJGPP stack size,  Prev: DJGPP specific code,  Up: GPC on DJGPP

3.3.9 I got an exception when accessing an `array [1 .. 4000000] of Byte'.
--------------------------------------------------------------------------

   Per default, the maximum stack size of a DJGPP application is 256K.
If you need more, you have to adjust it with the stubedit program, i.e.:

     stubedit your_app.exe minstack=5000K

   Another way is to add the following code to your program to define a
minimum stack size (here: 2 MB). This value will be honored even if a
user sets a lower value by using stubedit, so this method might be a
little safer.

   Note: The syntax given here is valid for GPC releases of May 2000
and newer.

     {$ifdef DJGPP}
     const
       MinStackSize : Cardinal = $200000; asmname '_stklen';
     {$endif}

   Still, it might be a good idea to use pointers for large structures,
and allocate the memory at runtime.


File: gpc,  Node: Strings in GPC,  Next: Getting Help,  Prev: GPC on DJGPP,  Up: FAQ

3.4 Strings
===========

* Menu:

* String schema::               What's this confusion about strings?
* Strings in variant records::  Overlaying strings in variant records
* Length byte::                 Why does `s[0]' not contain the length?
* Short strings::               Support for BP compatible short strings
* C strings::                   What about C strings?


File: gpc,  Node: String schema,  Next: Strings in variant records,  Up: Strings in GPC

3.4.1 What's this confusion about strings?
------------------------------------------

   Turbo Pascal strings have a length byte in front. Since a byte has
the range 0 .. 255, this limits a string to 255 characters. However,
the Pascal string schema, as defined in section 6.4.3.3.3 of the
ISO-10206: 1990 Extended Pascal standard, is a schema record:

     type
       String (Capacity : Integer) = record
         Length : 0 .. Capacity;
         String : packed array [1 .. Capacity + 1] of Char
       end;

   The `+ 1' is a GPC extension to make it feasible to automatically
add the `#0' terminator when passing or assigning them to CStrings.
Thus at the expense of a little added complexity (must declare
capacity, don't use `GetMem' without explicit initialization of the
`Capacity' field, and the additional space requirement) you can now
have very long strings.


File: gpc,  Node: Strings in variant records,  Next: Length byte,  Prev: String schema,  Up: Strings in GPC

3.4.2 Overlaying strings in variant records
-------------------------------------------

   Q: Should the different variants in a variant record overlay in the
same memory? Previous Pascals I have used have guaranteed this, and
I've got low-level code that relies on this. The variants are not the
same length, and they are intended not to be.

   A: No, this is intentional so that the discriminants are not
overwritten, and they can be properly initialized in the first place.
Consider:

     record
     case Boolean of
       False: (s1 : String (42));
       True:  (s2 : String (99));
     end;

   If the strings would overlay, in particular their discriminants
would occupy the same place in memory. How should it be initialized?
Either way, it would be wrong for at least one of the variants...

   So, after a discussion in comp.lang.pascal.ansi-iso where this topic
came up concerning file variables (which also require some automatic
initialization and finalization), we decided to do this in GPC for all
types with automatic initialization and finalization (currently files
and schemata, in the future this might also be Delphi compatible
classes and user-defined initialized and finalized types), since the
standard does not guarantee variants to overlay, anyway...

   There are two ways in GPC to get guaranteed overlaying (both
non-standard, of course, since the standard does not assume anything
about internal representations; both BP compatible), `absolute'
declarations and variable type casts. E.g., in order to overlay a byte
array `b' to a variable `v':

     var
       b: array [1 .. SizeOf (v)] of Byte absolute v;

   Or you can use type-casting:

     type
       t = array [1 .. SizeOf (v)] of Byte;

   then `t (v)' can be used as a byte array overlayed to `v'.


File: gpc,  Node: Length byte,  Next: Short strings,  Prev: Strings in variant records,  Up: Strings in GPC

3.4.3 Why does `s[0]' not contain the length?
---------------------------------------------

   Q: In standard Pascal you expect `s[1]' to align with the first
character position of `s' and thus one character to the left is the
length of `s'. Thus `s[0]' is the length of `s'.  True?

   A: This holds for UCSD/BP strings (which GPC does not yet implement,
but that's planned). The only strings Standard Pascal knows are arrays
of char without any length value.

   GPC also supports Extended Pascal string schemata (*note String
schema::), but they also don't have a length byte at "position 0", but
rather a `Length' field (which is larger than one byte).


File: gpc,  Node: Short strings,  Next: C strings,  Prev: Length byte,  Up: Strings in GPC

3.4.4 Support for BP compatible short strings
---------------------------------------------

   Q: Two different kinds of strings with the same name - `String' -
does make a bit of confusion. Perhaps the oldstyle strings could be
renamed `short string' ?

   A: When we implement the short strings, we'll have to do such a
distinction. Our current planning goes like this:

   `String (N)': string schema (EP compatible)

   `String [N]': short string (UCSD/BP compatible, where N must be <=
255)

   `String': dependent on flags, by default undiscriminated schema, but
in BP mode (or with a special switch) short string of capacity 255
(UCSD/BP compatible).

   Q: So when will these short strings be available?

   A: It's been planned for over a year. The delay has been caused by
more pressing problems.


File: gpc,  Node: C strings,  Prev: Short strings,  Up: Strings in GPC

3.4.5 What about C strings?
---------------------------

   A C string (`char *') is an array of char, terminated with a `#0'
char.

   C library functions require C, not Pascal style string arguments.
However, Pascal style strings are automatically converted to C style
strings when passed to a routine that expects C style strings. This
works only if the routine reads from the string, not if it modifies it.

   E.g., this is how you could access the `system()' call in your C
library (which is not necessary anymore, since `Execute' is already
built-in):

     program SysCall;
     
     function System (Name : CString): Integer; asmname 'system';
     
     var
       Result : Integer;
     
     begin
       Result := System ('ls -l');
       WriteLn ('system() call returned : ', Result)
     end.

   You could use the type `PChar' instead of `CString'. Both `CString'
and `PChar' are predefined as `^Char' - though we recommend `CString'
because it makes it clearer that we're talking about some kind of
string rather than a single character.

   A lot of library routines in Pascal for many applications exist in
the GPC unit and some other units. Where available, they should be
preferred (e.g. `Execute' rather than `system()', and then you won't
have to worry about `CString's.)

   Do *not* pass a C style string as a `const' or `var' argument if the
C prototype says `const char *' or you will probably get a segfault.


File: gpc,  Node: Getting Help,  Next: Miscellaneous FAQ,  Prev: Strings in GPC,  Up: FAQ

3.5 Getting Help
================

   Please read the GPC Manual (info files or other formats) as well as
the `README' and `BUGS' files that come with GPC (usually installed in
directory `/usr/local/doc/gpc'), plus other docs that might help (the
DJGPP FAQ if you use DJGPP, etc.) before you send email to the
maintainers or mailing list.

   In particular, the `BUGS' file contains information on how to submit
bug reports in the most efficient way.

   The `Support' chapter of the GPC Manual tells you where to find more
information about GPC and how to contact the GPC developers.  (*note
Support::)


File: gpc,  Node: Miscellaneous FAQ,  Prev: Getting Help,  Up: FAQ

3.6 Miscellaneous
=================

* Menu:

* Contributing::           I want to contribute; where do I start?
* GPC FTP and WWW sites::  Where is the GNU Pascal FTP site? WWW?
* About the FAQ::          About this FAQ


File: gpc,  Node: Contributing,  Next: GPC FTP and WWW sites,  Up: Miscellaneous FAQ

3.6.1 I want to contribute; where do I start?
---------------------------------------------

   If you want to contribute, please write to the mailing list, *Note
Mailing List::.


File: gpc,  Node: GPC FTP and WWW sites,  Next: About the FAQ,  Prev: Contributing,  Up: Miscellaneous FAQ

3.6.2 Where is the GNU Pascal FTP site? WWW?
--------------------------------------------

   The GPC homepage on the web is
`http://home.pages.de/~GNU-Pascal/'.

   For now, this same page appears at
`http://agnes.dida.physik.uni-essen.de/~gnu-pascal/'.

   The master FTP site for GNU Pascal is
`agnes.dida.physik.uni-essen.de'.

   GNU Pascal related files can be found in
`ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/'.

   GPC To-Do list, latest features, fixed bugs:
`http://agnes.dida.physik.uni-essen.de/~gnu-pascal/todo.html'


File: gpc,  Node: About the FAQ,  Prev: GPC FTP and WWW sites,  Up: Miscellaneous FAQ

3.6.3 About this FAQ
--------------------

   Current Maintainer: Russ Whitaker <russ@ashlandhome.net>

   This is the second incarnation of the GNU Pascal FAQ list. Comments
about, suggestions for, or corrections to this FAQ list are welcome.

   This FAQ is based on GNU Pascal Frequently-Asked Questions List,
Edition 0.4, for GPC version 2.0, November 1996 by J.J. van der Heijden
<j.j.vanderheijden@student.utwente.nl>.

   Please make sure to include in your mail the version number of the
document to which your comments apply (you can find the version at the
beginning of this FAQ list).

   Many people have contributed to this FAQ, only some of them are
acknowledged above. Much of the info in, and inspiration for this FAQ
list was taken from the GPC mailing list traffic, so you may have
(unbeknownst to you) contributed to this list.


File: gpc,  Node: Installation,  Next: Borland Pascal,  Prev: FAQ,  Up: Top

4 How to download, compile and install GNU Pascal.
**************************************************

* Menu:

* Download::              Where and what to download
* Binary Distributions::  How to install a binary distribution
* Compiling GPC::         How to compile GPC
* Compilation Notes::     Compilation notes for specific platforms
* Cross-Compilers::       Building and Installing a cross-compiler
* Crossbuilding::         Crossbuilding a compiler


File: gpc,  Node: Download,  Next: Binary Distributions,  Up: Installation

4.1 Where and what to download
==============================

   The master server for GNU Pascal is
`agnes.dida.physik.uni-essen.de'. Official and beta releases of the
compiler with sources and binaries for many platforms as well as other
GNU Pascal related files can be found in

     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/'

   You can find binary distributions for many platforms in the
subdirectory `binary'. The archive files are named
`gpc-VERSION.PLATFORM.EXTENSION' - for example
`gpc-2.1.alpha-unknown-linux-gnu.tar.gz' for GPC version 2.1 on an
Alpha workstation running the Linux kernel with GNU C Library, or
`gpc-20000616.i586-pc-djgppv201.zip' for GPC version 20000616 on an
i586 PC running DOS with DJGPP version 2.01.

   After you have downloaded the correct archive file for your
platform, please read the installation notes on how to install such a
binary distribution.

   If you are running Dos or MS Windows, you will need additional tools
- see "What else to download and where" below.

Current snapshots
-----------------

   GNU Pascal is subject to steady development. You can download the
current snapshot (source only, use at your own risk) via anonymous FTP
from:

     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/alpha/'

or via anonymous CVS from:

     CVS root:
       :pserver:anonymous@agnes.dida.physik.uni-essen.de:/usr/local/cvsroot
     Password:
       anonymous
     Command:
       checkout gpc

   Please read the installation notes on how to compile the source from
a distribution or a CVS checkout.

What else to download and where
-------------------------------

   When you are using GNU Pascal on a DOS system, you will need either
the DJGPP or the EMX development environment (see below). On an OS/2
system, you will need EMX. On an MS Windows 95/98/NT system you will
need either the CygWin or the mingw32 environment.

   GNU Pascal uses the compiler back-end from the GNU Compiler
Collection, GNU CC or GCC. If you want to compile GPC, you will need
the source of GCC as well as the source of GPC itself. For the current
version, please download `version 2.95.x' from a GNU FTP mirror (see
the list on the GNU home page, `http://www.gnu.org/gnu/order/ftp.html',
for the site closest to you).

Libraries
---------

   For some of GPC's units, you will need some standard libraries. In
particular:

Unit             Platform              Library
CRT              Unix/terminal         ncurses >= 5.0 (1), (2)
CRT              Unix/X11              PDCurses (2)
CRT              Dos, MS-Windows       PDCurses (3)
GMP              any                   gmp
RegEx            any                   rx
(debugging)      Unix, MS-Windows      ElectricFence (4)

   Notes:

   (1) ncurses version 5.0 or newer is strongly recommended because
older versions contain a bug that severely affects CRT programs.

   (2) You can install both ncurses and PDCurses on a Unix system, and
choose at compile time whether to generate a terminal or X11 version of
your program.

   (3) ncurses also runs under MS-Windows with CygWin (not mingw32,
however), but doesn't appear to behave much differently from PDCurses
on that platform.

   (4) ElectricFence is not used by any unit, but can be used for
debugging memory allocation bugs by simply linking it (see the
accompanying documentation).

   You can find those libraries on many places on the Net. Also, many
GNU/Linux distributions, DJGPP mirrors and other OS distributions
already contain some of the libraries. In any case, you can find the
sources of the libraries (sometimes together with patches that you
should apply before building if you choose to build from the sources)
and binaries for some platforms in

     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/'

DJGPP
-----

   DJGPP (http://www.delorie.com/djgpp/) is available from any SimTel
mirror in the `gnu/djgpp' subdirectory; for FTP addresses look into the
DJGPP FAQ (http://www.delorie.com/djgpp/v2faq/). For using GNU Pascal
you need at least

   - the C library, `v2/djdev201.zip', and

   - `binutils' (assembler, etc.), `v2gnu/bnu270b.zip'.

   We also recommend you to get:

   - the `make' utility, `v2gnu/mak375b.zip'

   - the GNU debugger, `v2gnu/gdb416b.zip'

   - the DJGPP FAQ, `v2faq/faq211b.zip'

   - the GRX graphics library, `http://www.gnu.de/software/GRX/'

   - PENG, `http://fjf.gnu.de/peng.html', an integrated development
     environment, similar to BP's one, written in GNU Pascal, or

   - RHIDE, `v2app/rhide.zip', another integrated development
     environment.

EMX
---

   EMX is an environment for creating 32-bit applications for DOS and
OS/2.  It is available from:

     `http://www.leo.org/pub/comp/os/os2/leo/gnu/emx+gcc/index.html'

   To develop EMX programs with GNU Pascal you need at least

   - the EMX runtime package, `emxrt.zip',

   - the EMX development system, `emxdev*.zip', and

   - the GNU development tools, `gnudev*.zip'.

   If your DOS box has DPMI (it does if you are using MS Windows or
OS/2) you will also need RSX, available from the same sites as EMX in
the subdirectory `rsxnt'.

   The GNU development tools contain the GNU C compiler which is in fact
not needed to use GNU Pascal. However, the C library _is_ needed.

CygWin
------

   CygWin is an environment which implements a POSIX layer under MS
Windows, giving it large parts of the functionality of Unix. CygWin
contains development tools such as an assembler, a linker, etc. GPC
needs for operation. More information about CygWin can be found at:

     `http://www.cygnus.com/cygwin/'

mingw32
-------

   The Minimalists' GNU Win32 environment, mingw32, allows a large
number of Unix programs - including GPC and GCC - to run under MS
Windows 95/98/NT using native MS libraries. mingw32 ressources can be
found at:

     `http://agnes.dida.physik.uni-essen.de/~janjaap/mingw32/'
     `http://www.xraylith.wisc.edu/~khan/software/gnu-win32/'


File: gpc,  Node: Binary Distributions,  Next: Compiling GPC,  Prev: Download,  Up: Installation

4.2 Installation instructions for a GPC binary distribution
===========================================================

   To install a binary distribution, `cd' to the root directory and
unpack the archive while preserving the stored directory structure.
Under a Unix compatible system with GNU `tar' installed, the following
(performed as `root') will do the job:

     # cd /
     # tar xzf ARCHIVE.tar.gz

   If you are using a `tar' utility other than GNU `tar', it might be
necessary to do the above in an explicit pipe:

     # cd /
     # gzip -c -d ARCHIVE.tar.gz | tar xf -

   If you want to install a GPC binary distribution in another directory
than it was prepared for (for example, if you do not have root access
to the computer and want to install GPC somewhere under your home
directory), you can do the following:

   - Unpack the archive file in a directory of your choice (see above).

   - `cd' to the "prefix" directory of the distribution (for instance
     `usr/local').

   - Run the script `install-gpc-binary', available from
     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/current/binary/'.

   - Follow the instructions in the script.

   To install a ZIP archive under DOS with `PKunzip', `cd' the the
appropriate directory (usually `\' for EMX, `\DJGPP' for DJGPP), then
call `PKunzip' with the `-d' option:

     C:\> cd djgpp
     C:\DJGPP> pkunzip -d ARCHIVE.zip

   where `ARCHIVE.zip' is the name of the distribution file.

   For DJGPP you must edit your `djgpp.env' in the `DJGPP' directory to
complete the installation: Please copy the entries from `[gcc]' to
create a new `[gpc]' section. The result may look as follows:

     [gcc]
     COMPILER_PATH=%/>;COMPILER_PATH%%DJDIR%/bin
     LIBRARY_PATH=%/>;LIBRARY_PATH%%DJDIR%/lib
     
     [gpc]
     COMPILER_PATH=%/>;COMPILER_PATH%%DJDIR%/bin
     LIBRARY_PATH=%/>;LIBRARY_PATH%%DJDIR%/lib

   If you are using the DJGPP version of GPC but do not have a `DJGPP'
directory, please download and install DJGPP (*note Download::).

   Binary distributions include `libgcc.a' and `specs', files that are
normally part of GCC. If you have GCC installed, they will be replaced
unless you manually install the archive.


File: gpc,  Node: Compiling GPC,  Next: Compilation Notes,  Prev: Binary Distributions,  Up: Installation

4.3 Compiling GPC
=================

   The preferred way to distribute GNU software is distribution of the
source code. However, it can be a non-trivial exercise to build GNU
Pascal on some non-Unix systems, so we also provide ready-to-run
binaries for a number of platforms. (See *Note Binary Distributions::
for how to install a binary distribution.)

   GPC is based on the GNU Compiler Collection, GNU CC or GCC. You will
need the GCC sources to build it. It must be the same version as the
one GPC is implemented with - `version 2.95.x' as of this writing.
Although you need GCC to build the GNU Pascal compiler, you don't need
GCC to compile Pascal programs once GNU Pascal is installed. (However,
using certain libraries will require compiling C wrappers, so it is a
good idea to install the C compiler as well.)

   Because GNU Pascal shares its back-end with GCC, it should run on any
system supported by GCC. A full list of platforms supported by GCC can
be found in *Note the GCC installation instructions: (gcc)Installation.

   The GCC source can be obtained from any mirror of the GNU FTP site,
`ftp://ftp.gnu.org/gnu/gcc/'. The "core" distribution is sufficient for
GPC.

   Here is the generic procedure for installing GNU Pascal on a Unix
system. See *Note Compilation Notes:: for extra information needed to
install GPC on DOS-like platforms.

  1. Checking the prerequisites

     Make sure that GNU make is installed. (In the following, we will
     simply speak of `make' when invoking GNU make; you might need to
     call `gmake' instead.)

     For extracting the example programs from the documentation to the
     `doc/docdemos' directory a non-crippled `sed' is needed.  GNU sed
     is known to work.

     If you have checked out the GPC source from CVS, you will have to
     rebuild most derived files, so you will need additional tools:
     `bison', `flex', `makeinfo', `gperf', and `autoconf'. Make sure
     that these are installed.

     If you want to build the GPC WWW pages you will also need:
     `texi2html' version 1.61 (older versions are missing some needed
     features; newer versions suffer from a bug), `texi2dvi', TeX,
     `gzip', `dvips', `dviselect', and `dviconcat'.

     If you run into trouble during the installation process, please
     check whether you are using outdated versions of the required
     utilities and upgrade if necessary.

     The GNU versions of the packages above are available from the GNU
     FTP server (ftp://ftp.gnu.org) or any of its mirrors.  Package
     PACKAGE is usually located in the directory `gnu/PACKAGE'.

  2. Unpacking the source

     From a directory of your choice (e.g. `/home/fred'), unpack the
     GCC and GNU Pascal source distributions. This will create separate
     subdirectories for GCC and GPC. Let us assume `gcc-2.95.1' and
     `gpc-20000535' in this example.
          % cd /home/fred
          % gzip -c -d gcc-core-2.95.1.tar.gz | tar xf -
          % gzip -c -d gpc-20000535.tar.gz | tar xf -

     `cd' to the GPC directory and move the contents (a subdirectory
     `p') to the subdirectory `gcc' of the GCC directory:

          % cd /home/fred/gpc-20000535
          % mv p /home/fred/gcc-2.95.1/gcc/

     It is recommended, though not required, to use a separate
     directory for building the compiler, rather than compiling in the
     source directory. In this example, let us create
     `/home/fred/gpc-build' for this purpose:

          % mkdir /home/fred/gpc-build

     If you use a separate directory, you do not need to write into the
     GCC source directory once you have patched the GCC source (see
     below), and can build GPC for more than one platform from the same
     source tree.

     In case you are re-using a directory where you have already built
     GCC and/or GPC for a different target machine, do `make distclean'
     to delete all files that might be invalid. One of the files this
     deletes is `Makefile'; if `make distclean' complains that
     `Makefile' does not exist, it probably means that the directory is
     already suitably clean.

  3. Configuring and building GCC

     GNU Pascal is automatically configured with GCC. Configuration of
     GCC is treated in depth in *Note the GCC installation
     instructions: (gcc)Installation. The normal procedure is as
     follows:

     `cd' to the GPC build directory. From there, run the `configure'
     script in the GCC source directory:

          % cd /home/fred/gpc-build
          % /home/fred/gcc-2.95.1/configure --enable-languages=pascal

     This creates all the necessary config files, links and Makefile in
     the GCC object directory.

     Note 1: The configuration will prompt you for patching the GCC
     source for GPC support, so you need write access to that
     directory. All changes to GCC are surrounded by `#ifdef GPC ...
     #endif', so they should not interfere when you build a C compiler
     from this source tree.

     Note 2: The `--enable-languages=pascal' option means that we only
     want to build the Pascal compiler and not, for instance, the C++
     compiler.

     Note 3: The standard base directory for installing GCC and GPC is
     `/usr/local'. If you want to install files to an alternate
     directory DIR, specify `--prefix=DIR' when you run `configure'.

  4. Putting other GNU tools in place

     Some environments require other GNU tools (such as the GNU
     assembler or linker) instead of the standard system tools for GCC
     to work. (See the GCC installation instructions for details.) If
     this is the case for your system, install the required tools in
     the GPC build directory under the names `as', `ld', or whatever is
     appropriate. This will enable the compiler to find the proper
     tools for compilation of the program `enquire' (a part of GCC) and
     to install the GNU tools to a place where they are found by GCC
     but do not interfere with the standard system tools.

     Alternatively, you can do subsequent compilation using a value of
     the `PATH' environment variable such that the necessary GNU tools
     come before the standard system tools.

  5. Compiling GPC

     Once you are satisfied with the configuration as determined by
     `configure', you can build the compiler:

          % make

     Notice that this procedure will build the C compiler (and maybe
     some other compilers) too, because that is used to compile the GPC
     runtime library.

     Optionally, you may supply CFLAGS, LDFLAGS or RTSFLAGS. CFLAGS is
     used for compiler and RTS, RTSFLAGS are for RTS only, i.e.: `make
     CFLAGS="-O2" RTSFLAGS=-Wall'

  6. Completing the installation

     When everything has been compiled, you can check the installation
     process with:

          % make -n install

     To complete the installation, run the command `make install'. You
     need write access to the target directories (`/usr/local/bin',
     `/usr/local/lib', `/usr/local/info', `/usr/local/doc', and
     `/usr/local/man' in this example), so this is usually done as
     `root':

          % su -c "make install"

     If you want to install _only_ the Pascal compiler (for example if
     you already have the correct version of GCC installed), `cd' to the
     `gcc' subdirectory of the build directory (e.g.
     `/home/fred/gpc-build/gcc') and run `make pascal.install'. This
     installation process does *not* overwrite existing copies of
     `libgcc.a' or `specs', should they exist.

     Also from the `gcc' subdirectory you can do some more "exotic"
     builds. For instance, you can build the GPC WWW pages by typing
     `make pascal.html' or a binary distribution by typing `make
     pascal.bindist'. See the `Makefile' in that directory for more
     examples.


File: gpc,  Node: Compilation Notes,  Next: Cross-Compilers,  Prev: Compiling GPC,  Up: Installation

4.4 Compilation notes for specific platforms
============================================

* Menu:

* MS-DOS with DJGPP::        The DJGPP port of GNU compilers to MS-DOS.
* MS-DOS or OS/2 with EMX::  The EMX port of GNU compilers to MS-DOS and OS/2.
* MS Windows 95/98/NT::      Installation on a Windows 95/98/NT system.


File: gpc,  Node: MS-DOS with DJGPP,  Next: MS-DOS or OS/2 with EMX,  Up: Compilation Notes

4.4.1 MS-DOS with DJGPP
-----------------------

   The only compiler that is capable of compiling the GNU Compiler
Collection (GNU CC or GCC) under MS-DOS is GCC itself. In order to
compile GPC or GCC for MS-DOS with DJGPP you will therefore need either
a working copy of DJGPP installed, or you will have to cross-build from
a non-MS-DOS system.

   Building GPC under MS-DOS with DJGPP follows the same scheme as
building GPC under a Unix-like system: Place the `p' subdirectory in the
`gcc' directory and follow the instructions for compiling GCC. This
requires `bash' and many other tools installed, and you must be very
careful at many places to circumvent the limitations of the DOS
platform.

   Our preferred way to build GPC for DJGPP is to cross-build it from a
Unix-like platform - which is much easier. For instructions, see *Note
Cross-Compilers:: and *Note Crossbuilding::.


File: gpc,  Node: MS-DOS or OS/2 with EMX,  Next: MS Windows 95/98/NT,  Prev: MS-DOS with DJGPP,  Up: Compilation Notes

4.4.2 MS-DOS or OS/2 with EMX
-----------------------------

   EMX is a free 32-bit DOS extender which adds some properties of Unix
to MS-compatible DOS and IBM's OS/2 operating systems.

   As of this writing, we are not aware of current versions of GCC for
EMX, and EMX support in GPC has not been maintained. Please contact us
if you know about recent development in EMX and are interested in
continuing EMX support in GPC.


File: gpc,  Node: MS Windows 95/98/NT,  Prev: MS-DOS or OS/2 with EMX,  Up: Compilation Notes

4.4.3 MS Windows 95/98/NT
-------------------------

   There are two ports of the GNU development tools to MS Windows
95/98/NT: CygWin and mingw32.

   The CygWin environment implements a POSIX layer under MS Windows,
giving it large parts of the functionality of Unix. Thus, compiling GCC
and GPC under the CygWin environment can be done following the
instructions for compiling it under a Unix-like system (see *Note
Compiling GPC::).

   The Minimalists' GNU Win32 environment, mingw32, uses the native
`crtdll.dll' library of MS Winodws. It is much smaller than CygWin, but
it is not self-hosting and must be crossbuilt from another system (see
*Note Crossbuilding::).


File: gpc,  Node: Cross-Compilers,  Next: Crossbuilding,  Prev: Compilation Notes,  Up: Installation

4.5 Building and Installing a cross-compiler
============================================

   GNU Pascal can function as a cross-compiler for many machines.
Information about GNU tools in a cross-configuration can be found at
`ftp://ftp.cygnus.com/pub/embedded/crossgcc/'.

   Since GNU Pascal generates assembler code, you need a cross-assembler
that GNU Pascal can run, in order to produce object files. If you want
to link on other than the target machine, you need a cross-linker as
well. It is straightforward to install the GNU binutils to act as
cross-tools - see the installation instructions of the GNU binutils for
details.

   You also need header files and libraries suitable for the target
machine that you can install on the host machine. Please install them
under `PREFIX/PLATFORM/include/', for instance
`/usr/local/i386-pc-msdosdjgpp/include/' for a cross-compiler from a
typical Unix-like environmant to MS-DOS with DJGPP.

   Configuration and compilation of the compiler can then be done using
the scripts `cfgpc' and `mkgpc' which are included in the source
distribution in the subdirectory `p/script'. Please call them with the
`-h' option for instructions.


File: gpc,  Node: Crossbuilding,  Prev: Cross-Compilers,  Up: Installation

4.6 Crossbuilding a compiler.
=============================

   Using a cross-compiler to build GNU Pascal results in a compiler
binary that runs on the cross-target platform. This is called
"crossbuilding". A possible reason why anybody would want to do this,
is when the platform on which you want to run the GNU Pascal compiler
is not self-hosting. An example is mingw32.

   To crossbuild GNU Pascal, you have to install a cross-compiler for
your target first, see *Note Cross-Compilers::.

   As when building a cross-compiler, configuration and compilation of
the compiler can be done using the scripts `cfgpc' and `mkgpc' which
are included in the source distribution in the subdirectory `p/script'.
Please call them with the `-h' option for instructions.


File: gpc,  Node: Borland Pascal,  Next: Invoking GPC,  Prev: Installation,  Up: Top

5 A QuickStart Guide from Borland Pascal to GNU Pascal.
*******************************************************

   This chapter is intended to be a QuickStart guide for programmers
who are familiar with Borland Pascal.

   Throughout the manual, we talk of "Borland Pascal" or "BP" for
short, to refer to Borland Pascal version 7 for Dos protected mode.
Other versions of Borland Pascal and Turbo Pascall don't differ too
much, but this one was the very last Dos version Borland has published,
so in most if not all cases, you can safely substitute the version
you're familiar with.

   "Borland Pascal" and "Turbo Pascal" are registered trademarks of
Inprise Corp./Borland Inc.

* Menu:

* BP Compatibility::
* BP Incompatibilities::
* IDE versus command line::
* Comments::
* BP Compatible Compiler Directives::
* Units; GPI files and AutoMake::
* Optimization::
* Debugging::
* Objects::
* Strings in BP and GPC::
* Typed Constants::
* Bit; Byte and Memory Manipulation::
* User-defined Operators in GPC::
* Data Types in BP and GPC::
* Files::
* Built-in Constants::
* Built-in Operators in BP and GPC::
* Built-in Procedures and Functions::
* Special Parameters::
* Miscellaneous::
* BP and Extended Pascal::
* Portability hints::


File: gpc,  Node: BP Compatibility,  Next: BP Incompatibilities,  Up: Borland Pascal

5.1 BP Compatibility
====================

   GNU Pascal (GPC) is compatible to version 7 of Borland Pascal (BP)
to a large extent and comes with portable replacements of the BP
standard units.

   However, BP is a 16-bit compiler while GPC is a 32/64-bit compiler,
so the size of the `Integer' type, for instance, is 16 bits in BP, but
at least 32 bits in GPC. If a BP program has been designed with
portability in mind from the ground up, it may work with GPC without
any change. Programs which rely on byte order, on the internals or
sizes of data types or which use unportable things like interrupts and
assembler code, will need to be changed. The following section lists
the possible problems with solutions.

   The GPC Run Time System (RTS) is fairly complete, and you can use
all libraries written for GNU C from GNU Pascal, so there is much less
need to use unportable constructs than there was in BP. (For example,
BP's Turbo Vision library uses assembler to call a local procedure
through a pointer. With GPC you can do this in Pascal just as with
global procedures.) Please do not throw away the advantage of full
portability by sticking to those workarounds.

   We have successfully ported real-world projects (with several 10000s
of lines) from BP to GPC, so this is possible for you, too.


File: gpc,  Node: BP Incompatibilities,  Next: IDE versus command line,  Prev: BP Compatibility,  Up: Borland Pascal

5.2 BP Incompatibilities
========================

   This sections lists the remaining incompatibilities of GPC to BP,
and the problems you might encounter when porting BP programs from
16-bit Dos to other platforms, and gives solutions for them.

   By "incompatibilites" we mean problems that can arise when trying to
compile a valid BP program with GPC. Of course, there are many features
in GPC that BP doesn't know, but we call them extensions unless they
can break valid BP programs, so they are not mentioned here. The
subsequent sections of the `Borland Pascal' chapter mention a number of
useful extensions that you might want to know about but which will not
break your BP code.

* Menu:

* String type::
* Qualified identifiers::
* Assembler::
* Move; FillChar::
* Real type::
* Graph unit::
* OOP units::
* Keep; GetIntVec; SetIntVec::
* TFDDs::
* Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc.::
* Endianness assumptions::

   Some of the differences can be "overcome" by command-line switches.
As a summary:

     --borland-pascal -w --uses=System -D__BP_TYPE_SIZES__ --pack-struct
     -D__BP_RANDOM__ -D__BP_UNPORTABLE_ROUTINES__

   But please read the following notes, and don't use these switches
indiscriminately when not necessary. There are reasons why they are not
GPC's defaults.

* Menu:

* - -borland-pascal - disable GPC extensions::
* -w - disable all warnings::
* - -uses=System - Swap; HeapError; etc.::
* -D__BP_TYPE_SIZES__ - small integer types etc.::
* - -pack-struct - disable structure alignment::
* -D__BP_RANDOM__ - BP compatible pseudo random number generator::
* -D__BP_UNPORTABLE_ROUTINES__ - Intr; DosVersion; etc.::


File: gpc,  Node: String type,  Next: Qualified identifiers,  Up: BP Incompatibilities

5.2.1 String type
-----------------

   GPC's internal string format (Extended Pascal string schema) is
different from BP's. BP compatible "short strings" will be implemented
in GPC soon, but in the meantime, you'll have to live with the
difference. In general, GPC's format has many advantages (no length
limit of 255 characters, constant and reference parameters always know
about their capacity, etc.), but you will see differences if you:

   - declare a variable as `String' without a capacity. However, GPC
     will assume 255 then (like BP) and only warn about it (and not even
     this when using `--borland-pascal', see below), so that's not a
     real problem. The "clean" way, however, is to declare `String
     [255]' when you mean so (but perhaps you'll prefer `String
     (2000)'? :-).

   - access "character 0" which happens to hold the length in BP. This
     does not work with string schemata. Use `Length' to get the
     length, and `SetLength' to modify it.

   - try to `FillChar' a string, e.g.  `FillChar (StringVar, 256, 0);',
     which would overwrite the `Capacity' field. Using `FillChar
     (StringVar [1], ...);' is alright since it accesses the characters
     of the string, not the `Capacity' and `Length' fields. If you want
     to set the length to zero, use `SetLength' (see above). This is
     more efficient than clearing all the characters, anyway, and has
     the same effect for all normal purposes.

   - try to read or write strings from/to _binary_ files (`Text' files
     are no problem). You will have to rewrite the code. If you also
     want to get rid of the 255 character limit and handle endianness
     issues (see below) in one go, you can use the
     `ReadStringLittleEndian' etc. routines (*note Run Time System::),
     but if you need BP compatible strings (i.e., with a one-byte
     length field) in data files, you cannot use them (but you can
     easily modify them for this purpose).


File: gpc,  Node: Qualified identifiers,  Next: Assembler,  Prev: String type,  Up: BP Incompatibilities

5.2.2 Qualified identifiers
---------------------------

   GPC does not yet support "qualified identifiers". They will be
implemented soon. In the meantime, just don't use them, sorry. (In
general, using the same identifier in different units can easily be
confusing, so it's not bad practice to avoid this, anyway.)


File: gpc,  Node: Assembler,  Next: Move; FillChar,  Prev: Qualified identifiers,  Up: BP Incompatibilities

5.2.3 Assembler
---------------

   GPC's inline assembler is not compatible to BP's. It uses "AT&T
syntax", supports a large variety of processors and works together with
GPC's optimizer. So, either convert your inline assembly to AT&T
syntax, or (usually better) to Pascal, or put it into an external file
which you can assemble with your favourite (32 bit) assembler. A
tutorial for using the GPC inline assembler is available at
`ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/contrib/gpcasm.zip'

   Since many things you usually do with assembler in BP are provided
by GPC's Run Time System (RTS), you will not need the inline assembler
as often as in BP. (See *Note Portability hints::.)

   The same applies to BP's `inline' directive for hand-written machine
code. GPC's `inline' directive works for Pascal routines (*note
Miscellaneous::), so you'll have to convert any hand-written machine
code to Pascal (and thereby make it more readable, portable and easier
to maintain while still getting the performance of inline code).


File: gpc,  Node: Move; FillChar,  Next: Real type,  Prev: Assembler,  Up: BP Incompatibilities

5.2.4 Move; FillChar
--------------------

   GPC supports `Move' and `FillChar', and they're fully BP compatible.
However, some data structures have different internal formats which may
become relevant when using these procedures. E.g., using `Move' on file
variables does not work in GPC (there are reasons why assigning file
variables with `:=' is not allowed in Pascal, and circumventing this
restriction with `Move' is not a good idea). For other examples, see
*Note String type::, *Note Real type::, and *Note Endianness
assumptions::.


File: gpc,  Node: Real type,  Next: Graph unit,  Prev: Move; FillChar,  Up: BP Incompatibilities

5.2.5 Real type
---------------

   GPC does not support BP's 6-byte `Real' type. It supports `Single',
`Double' and `Extended' which, at least on the x86 and some other
processors, are compatible to BP.

   For BP's 6-byte `Real' type, GPC's `System' unit provides an
emulation, called `BPReal', as well as conversion routines to GPC's
`Real' type (which is the same as `Double'), called `RealToBPReal' and
`BPRealToReal'. You'll probably only need them when reading or writing
binary files containing values of the BP 6-byte real type. There are no
operators (e.g., `+') available for `BPReal', but since GPC supports
operator overloading, you could define them yourself (e.g., convert to
`Real', do the operation, and convert back). Needless to say that this
is very inefficient and should not be done for any serious
computations. Better convert your data after reading them from the file
and before writing them back, or simply convert your data files once
(the other types are more efficient even with BP on any non-prehistoric
processor, anyway).


File: gpc,  Node: Graph unit,  Next: OOP units,  Prev: Real type,  Up: BP Incompatibilities

5.2.6 Graph unit
----------------

   A somewhat BP compatible Graph unit exists but is distributed
separately due to its license. It is known to work under DJGPP and
Linux/x86, under development under Mingw, and should work under any
Unix system with X11 (but only tested on a few systems).


File: gpc,  Node: OOP units,  Next: Keep; GetIntVec; SetIntVec,  Prev: Graph unit,  Up: BP Incompatibilities

5.2.7 OOP units
---------------

   The OOP stuff (Turbo Vision etc.) is not yet completed, but work on
several projects is underway. If you want information about the current
status or access to devlopment source, please contact the GPC mailing
list.


File: gpc,  Node: Keep; GetIntVec; SetIntVec,  Next: TFDDs,  Prev: OOP units,  Up: BP Incompatibilities

5.2.8 Keep; GetIntVec; SetIntVec
--------------------------------

   The routines `Keep', `GetIntVec' and `SetIntVec' in the `Dos' unit
do not even make sense on DJGPP (32 bit Dos extender). If your program
uses these, it is either a low-level Dos utility for which porting to a
32 bit environment might cause bigger problems (because the internal
issues of DPMI become relevant which are usually hidden by DJGPP), or
it installs interrupt handlers which will have to be thought about more
carefully because of things like locking memory, knowing about and
handling the differences between real and protected mode interrupts,
etc. For these kinds of things, we refer you to the DJGPP FAQ (*note
DJGPP FAQ: (djgppfaq)Top.).


File: gpc,  Node: TFDDs,  Next: Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc.,  Prev: Keep; GetIntVec; SetIntVec,  Up: BP Incompatibilities

5.2.9 TFDDs
-----------

   The internal structure of file variables (`FileRec' and `TextRec' in
BP's `Dos' unit and `TFileRec' and `TTextRec' in BP's `WinDos' unit) is
different in GPC.  However, as far as "Text File Device Drivers"
(TFDDs) are concerned, GPC offers a more powerful mechanism. Please see
the RTS reference (*note Run Time System::), under `AssignTFDD'.


File: gpc,  Node: Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc.,  Next: Endianness assumptions,  Prev: TFDDs,  Up: BP Incompatibilities

5.2.10 Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc.
------------------------------------------------

   Those few routines in the `System' unit that deal with segmented
pointers (e.g., `Ptr') are emulated in such a way that such ugly BP
constructs like
     PInteger (Ptr (Seg (a), Ofs (a) + 6 * SizeOf (Integer)))^ = 42
   work in GPC, but they do not provide access to absolute memory
addresses. Neither do `absolute' variables (which take a simple address
in the program's address space in GPC, rather than a segmented
address), and the `Mem' and `Port' arrays don't exist in GPC.

   As a replacement for `Port' on x86 processors, you can use the
routines provided in the `Ports' unit, *Note Ports::. If you want to
access absolute memory addresses in the first megabyte under DJGPP, you
can't do this with normal pointers because DJGPP programs run in a
protected memory environment, unless you use a dirty trick called "near
pointer hack". Please see the DJGPP FAQ (*note DJGPP FAQ:
(djgppfaq)Top.) for this and for other ways.

   For similar reasons, the variable `PrefixSeg' in the `System' unit
is not supported. Apart from "TSR"s, its only meaningful use in BP
might be the setting of environment variables.  GPC provides the
`SetEnv' and `UnSetEnv' procedures for this purpose which you can use
instead of any BP equivalents based on `PrefixSeg'. (However note that
they will set the program's own and its childs' environment, not its
parent's environment. This is a property - most people call it a
feature - of the environments, including DJGPP, that GPC compiled
programs run in.)


File: gpc,  Node: Endianness assumptions,  Next: - -borland-pascal - disable GPC extensions,  Prev: Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc.,  Up: BP Incompatibilities

5.2.11 Endianness assumptions
-----------------------------

   GPC also runs on big-endian systems (*note Endianness::). This is,
of course, a feature of GPC, but might affect your programs when
running on a big-endian system if they make assumptions about
endianness, e.g., by using type casts (or `absolute' declarations or
variant records misused as type casts) in certain ways. Please see the
demo program `absdemo.pas' for an example and how to solve it.

   Endianness is also relevant (the more common case) when exchanging
data between different machines, e.g. via binary files or over a
network. Since the latter is not easily possible in BP, and the
techniques to solve the problems are mostly the same as for files, we
concentrate on files here.

   First, you have to choose the endianness to use for the file. Most
known data formats have a specified endianness (usually that of the
processor on which the format was originally created). If you define
your own binary data format, you're free to choose the endianness to
use.

   Then, when reading or writing values larger than one byte from/to
the file, you have to convert them. GPC's Run Time System supports this
by some routines. E.g., you can read an array from a little-endian file
with the procedure `BlockReadLittleEndian', or write one to a
big-endian file with `BlockWriteBigEndian'.  _Note:_ The endianness in
the procedure names refers to the file, not the system - the routines
know about the endianness of the system they run on, but you have to
tell them the endianness of the file to use. This means you do not have
to (and must not) use an `ifdef' to use the version matching the
system's endianness.

   When reading or writing records or other more complicated
structures, either read/write them field by field using
`BlockReadBigEndian' etc., or read/write them with the regular
`BlockRead' and `BlockWrite' procedures and convert each field after
reading or before writing using procedures like `ConvertFromBigEndian'
or `ConvertToLittleEndian' (but remember, when writing, to undo the
conversion afterwards, if you want to keep using the data - this is not
necessary with `BlockWriteLittleEndian' etc.).

   Especially for strings, there are ready-made procedures like
`ReadStringBigEndian' or `WriteStringLittleEndian' which will
read/write the length as a 64 bit value (much space for really long
strings :-) in the given endianness, followed by the characters (which
have no endianness problem).

   All these routines are described in detail in the RTS reference
(*note Run Time System::), under `endianness'. The demo program
`endiandemo.pas' contains an example on how to use these routines.


File: gpc,  Node: - -borland-pascal - disable GPC extensions,  Next: -w - disable all warnings,  Prev: Endianness assumptions,  Up: BP Incompatibilities

5.2.12 - -borland-pascal - disable GPC extensions
-------------------------------------------------

   GPC warns about some BP constructs which are especially "dirty",
like misusing typed constants as initialized variables. GPC also
supports some features that may conflict with BP code, like macros.
The command line option `--borland-pascal' disables both, so you might
want to use it for a first attempt to compile your BP code under GPC.
However, we suggest you try compiling without this switch and fixing
any resulting problems as soon as you've become acquainted with GPC.


File: gpc,  Node: -w - disable all warnings,  Next: - -uses=System - Swap; HeapError; etc.,  Prev: - -borland-pascal - disable GPC extensions,  Up: BP Incompatibilities

5.2.13 -w - disable all warnings
--------------------------------

   Even in `--borland-pascal' mode, GPC may warn about some dangerous
things. To disable *all* warnings, you can use the `-w' option (note:
lower-case `w'!). This is not recommended at all, but you may consider
it more BP compatible...


File: gpc,  Node: - -uses=System - Swap; HeapError; etc.,  Next: -D__BP_TYPE_SIZES__ - small integer types etc.,  Prev: -w - disable all warnings,  Up: BP Incompatibilities

5.2.14 - -uses=System - Swap; HeapError; etc.
---------------------------------------------

   A few exotic BP routines and declarations (e.g., `Swap' and
`HeapError') are contained in a `System' unit, *Note System::, which
GPC (unlike BP) does not automatically use in each program. To use it,
you can add a `uses System;' clause to your program. If you don't want
to change your code, the command line option `--uses=System' will do
the same.


File: gpc,  Node: -D__BP_TYPE_SIZES__ - small integer types etc.,  Next: - -pack-struct - disable structure alignment,  Prev: - -uses=System - Swap; HeapError; etc.,  Up: BP Incompatibilities

5.2.15 -D__BP_TYPE_SIZES__ - small integer types etc.
-----------------------------------------------------

   Since GPC runs on 32 and 64 bit platforms, integer types have larger
sizes than in BP. However, if you use the `System' unit (*note -
-uses=System - Swap; HeapError; etc.::) and define the symbol
`__BP_TYPE_SIZES__' (by giving `-D__BP_TYPE_SIZES__' on the command
line), it will redeclare the types to the sizes used by BP. This is
less efficient and more limiting, but might be necessary if your
program relies on the exact type sizes.


File: gpc,  Node: - -pack-struct - disable structure alignment,  Next: -D__BP_RANDOM__ - BP compatible pseudo random number generator,  Prev: -D__BP_TYPE_SIZES__ - small integer types etc.,  Up: BP Incompatibilities

5.2.16 - -pack-struct - disable structure alignment
---------------------------------------------------

   GPC by default aligns fields of records and arrays suitably for
higher performance, while BP doesn't. If you don't want the alignment
(e.g., because the program relies on the internal format of your
structures), either declare the relevant structures as `packed' (which
BP also accepts, but ignores), or give the `--pack-struct' option.


File: gpc,  Node: -D__BP_RANDOM__ - BP compatible pseudo random number generator,  Next: -D__BP_UNPORTABLE_ROUTINES__ - Intr; DosVersion; etc.,  Prev: - -pack-struct - disable structure alignment,  Up: BP Incompatibilities

5.2.17 -D__BP_RANDOM__ - BP compatible pseudo random number generator
---------------------------------------------------------------------

   GPC uses a more elaborate pseudo random number generator than BP
does. Using the `Random' and `Randomize' functions works the same way,
but there is no `RandSeed' variable (but a `SeedRandom' procedure).
However, if you use the `System' unit (*note - -uses=System - Swap;
HeapError; etc.::) and define the symbol `__BP_RANDOM__' (by giving
`-D__BP_RANDOM__' on the command line), it will provide a 100% BP
compatible pseudo random number generator, including the `RandSeed'
variable, which will produce exactly the same sequence of pseudo random
numbers that BP's pseudo random number generator does. Even the
`Randomize' function will then behave exactly like in BP.


File: gpc,  Node: -D__BP_UNPORTABLE_ROUTINES__ - Intr; DosVersion; etc.,  Prev: -D__BP_RANDOM__ - BP compatible pseudo random number generator,  Up: BP Incompatibilities

5.2.18 -D__BP_UNPORTABLE_ROUTINES__ - Intr; DosVersion; etc.
------------------------------------------------------------

   A few more routines in the `Dos' and `WinDos' units besides the ones
mentioned under *Note Keep; GetIntVec; SetIntVec::, like `Intr' or
`DosVersion', are meaningless on non-Dos systems. By default, the `Dos'
unit does not provide these routines (it only provides those that are
meaningful on all systems, which are most of its routines, including
the most commonly used ones). If you need the unportable ones, you get
them by defining the symbol `__BP_UNPORTABLE_ROUTINES__' (by giving
`-D__BP_UNPORTABLE_ROUTINES__' on the command line). If you use `Intr'
or `MsDos', your program will only compile under DJGPP then. Other
routines, e.g. `DosVersion' are emulated quite roughly on other
systems. Please see the notes in the `Dos' unit (*note Dos::) for
details.


File: gpc,  Node: IDE versus command line,  Next: Comments,  Prev: BP Incompatibilities,  Up: Borland Pascal

5.3 IDE versus command line
===========================

   On the Dos (DJGPP) and Linux platforms, you can use RHIDE for GNU
Pascal; check the subdirectories of your DJGPP distribution.

   Unfortunately, there is no IDE which would run on all platforms. We
are working on it, but this will take some time. Please be patient - or
offer your help!

   Without an IDE, the GNU Pascal Compiler, GPC, is called about like
the command-line version of the Borland Pascal Compiler, BPC. Edit your
source file(s) with your favorite ASCII editor, then call GNU Pascal
with a command line like

     C:\GNU-PAS> gpc hello.pas -o hello.exe

on your Dos or OS/2 box or

     myhost:/home/joe/gnu-pascal> gpc hello.pas -o hello

on your Unix (or Unix-compatible) system.

   Don't omit the `.pas' suffix: GPC is a common interface for a Pascal
compiler, a C, ObjC and C++ compiler, an assembler, a linker, and
perhaps an Ada and a FORTRAN compiler. From the extension of your
source file GPC figures out which compiler to run. GPC recognizes
Pascal sources by the extension `.pas', `.p', `.pp' or `.dpr'.

   The `-o' is a command line option which tells GPC how the executable
has to be named. If not given, the executable will be called `a.out'
(Unix) or `a.exe' (Dos). However, you can use the
`--executable-file-name' to tell GPC to always call the executable like
the source (with the extension removed under Unix and changed to `.exe'
under Dos).

   Note that GPC is case-sensitive concerning file names and options,
so it will _not_ work if you type

     C:\GNU-PAS> GPC HELLO.PAS -O HELLO.EXE

   GPC is a very quiet compiler and doesn't print anything on the
screen unless you request it or there is an error. If you want to see
what is going on, invoke GPC with additional options:

     -Q            "don't be quiet"  (or: Quassel-Modus in German)

(with _capital_ `Q'!) means that GPC prints out the names of procedures
and functions it processes, and

     --verbose

or abbreviated

     -v

means that GPC informs you about the stages of compilation, i.e.
preprocessing, compiling, assembling, and linking.

   One example (this time for OS/2):

     [C:\GNU-Pascal] gpc --verbose -Q hello.pas

   Throughout this chapter, we will tell you about a lot of
command-line switches. They are all invoked this way.

   After compilation, there will be an executable `hello' file in the
current directory. (`hello.exe' on Dos or OS/2.) Just run it and enjoy.
If you're new to Unix, please note that the current directory is not on
the PATH in most installations, so you might have to run your program
as `./hello'. This also helps to avoid name conflicts with other
programs. Such conflicts are especially common with the program name
`test' which happens to be a standard utility under Unix that does not
print any output. If you call your program `test.pas', compile it, and
then invoke `test', you will usually not run your program, but the
utility which leads to mysterious problems. So, invoke your program as
`./test' or, better yet, avoid the name `test' for your programs.

   If there are compilation errors, GNU Pascal will not stop
compilation after the first one - as Borland Pascal does - but try to
catch all errors in one compilation. If you get more error messages
than your screen can hold, you can catch them in a file (e.g.
`gpc.out') or pipe them to a program like `more' in the following way:

     gpc hello.pas 2> gpc.out

   This works with OS/2 and any bash-like shell under Unix; for Dos you
must get a replacement for `command.com' which supports this kind of
redirection, or use the `redir' utility (see also the DJGPP FAQ, *Note
DJGPP FAQ: (djgppfaq)Top.):

     C:\GNU-PAS> redir -eo gpc hello.pas -o hello.exe | more

   You can also use Borland's IDE for GNU Pascal on the Dos platform:
Install the GNU Pascal Compiler in the Tools menu (via Options/Tools).

     Name:       GNU Pascal
     Path:       gpc
     Arguments:  $SAVE ALL --executable-file-name $NAME($EDNAME).pas
     HotKey:     Shift+F9

   Note once more that GPC is case-sensitive, so it is important to
specify `.pas' instead of the `.PAS' Borland Pascal would append
otherwise!

   You can include more command-line arguments to GNU Pascal (e.g.
`--automake'; see below) as you will learn more about them.

   Since Borland Pascal will try to recompile your program if you use
its `Run' menu function, you will need another tool to run your program:

     Name:       Run Program
     Path:       command.com
     Arguments:  /c $NAME($EDNAME)
     HotKey:     Shift+F10


File: gpc,  Node: Comments,  Next: BP Compatible Compiler Directives,  Prev: IDE versus command line,  Up: Borland Pascal

5.4 Comments
============

   GPC supports comments surrounded by `{ }' and `(* *)', just like BP
does. According to the ISO 7185 and ISO 10206 standards, Pascal allows
comments opened with `(*' and closed with `}'. Borland Pascal does not
support such "mixed" comments, so you might have sources where passages
containing comments are "commented out" using the other kind of comment
delimiters. GPC's default behaviour is (like BP) not to allow mixed
comments, so you don't need to worry about this. However, if you happen
to like mixed comments, you can turn them on either by a command-line
option, or by a compiler directive:

     --mixed-comments     {$mixed-comments}    (*$mixed-comments*)

   GPC supports nested comments (e.g., `{ foo { bar } baz }'), but they
are disabled by default (compatible to BP which doesn't know nested
comments at all). You can enable them with the option
`--nested-comments' (or the equivalent compiler directive)

   GPC also supports Delphi style comments starting with `//' and
extending until the end of the line. This comment style is activated by
default unless one of the `--standard-pascal', `--extended-pascal',
`--object-pascal' or `--borland-pascal' dialect options is given. You
can turn them on or off with the `--[no-]delphi-comments' option.


File: gpc,  Node: BP Compatible Compiler Directives,  Next: Units; GPI files and AutoMake,  Prev: Comments,  Up: Borland Pascal

5.5 BP Compatible Compiler Directives
=====================================

   All of BP's one-letter compiler directives are supported by GPC,
though some of them are ignored because they are not necessary under
GPC. Besides, GPC supports a lot more directives. For an overview, see
*Note Compiler Directives::.


File: gpc,  Node: Units; GPI files and AutoMake,  Next: Optimization,  Prev: BP Compatible Compiler Directives,  Up: Borland Pascal

5.6 Units, GPI files and AutoMake
=================================

   You can use units in the same way as in Borland Pascal. However,
there are some additional features.

   Concerning the syntax of a unit, you can, if you want, use Extended
Pascal syntax to specify a unit initializer, i.e., instead of writing

     begin
       ...
     end.

at the end of the unit, you can get the same result with

     to begin do
       begin
         ...
       end;

and there also exists

     to end do
       begin
         ...
       end;

which specifies a finalization routine. You can use this instead of
Borland Pascal's exit procedures, but for compatibility, the included
`System' unit also provides the `ExitProc' variable. The `to begin do'
and/or `to end do' parts must be followed by the final `end.'. See
*Note Modules::, for information about Extended Pascal modules, an
alternative to units.

   When GPC compiles a unit, it produces two files: an `.o' object file
(compatible with other GNU compilers such as GNU C) plus a `.gpi' file
which describes the interface.

   If you are interested in the internal format of GPI file, see *Note
GPI files::.

   If you want to compile a program that uses units, you must "make"
the project. (This is the command-line switch `-M' or the IDE keystroke
`F9' in BP.) For this purpose, GPC provides the command-line switch
`--automake':

     gpc --automake hello.pas

   If you want to force everything to be rebuilt rather than only
recompile changed files (`-B' or "build" in BP), use `--autobuild'
instead of `--automake':

     gpc --autobuild hello.pas

   For more information about the AutoMake mechanism, see *Note
AutoMake::.

   If you do not want to use the AutoMake mechanism for whatever
reason, you can also compile every unit manually and then link
everything together.

   GPC does not automatically recognize that something is a unit and
cannot be linked; you have to tell this by a command line switch:

     -c            only compile, don't link.

   (If you omit this switch when compiling a unit, you only get a
linker error message `undefined reference to `main''.  Nothing serious.)

   For example, to compile two units, use:

     gpc -c myunit1.pas myunit2.pas

   When you have compiled all units, you can compile a program that
uses them without using `--automake':

     gpc hello.pas

   However, using `--automake' is recommended, since it will recompile
units that were modified.

   You could also specify the program and the units in one command line:

     gpc hello.pas myunit1.pas myunit2.pas

   One of the purposes of writing units is to compile them separately.
However, GNU Pascal allows you to have one or more units in the same
source file (producing only one `.o' file but separate `.gpi' files).
You even can have a program and one or more units in one source file;
in this case, no `.o' file is produced at all.


File: gpc,  Node: Optimization,  Next: Debugging,  Prev: Units; GPI files and AutoMake,  Up: Borland Pascal

5.7 Optimization
================

   GNU Pascal is a 32/64 bit compiler with excellent optimization
algorithms (which are identically the same as those of GNU C). There
are six optimization levels, specified by the command line options
`-O', `-O2', ..., `-O6'.

   One example:

     program OptimizationDemo;
     
     procedure Foo;
     var
       A, B : Integer;
     begin
       A := 3;
       B := 4;
       WriteLn (A + B)
     end;
     
     begin
       Foo
     end.

   When GNU Pascal compiles this program with optimization (`-O3'), it
recognizes that the argument to `WriteLn' is the constant 7 - and
optimizes away the variables `A' and `B'. If the variables were global,
they would not be optimized away because they might be accessed from
other places, but the constant 7 would still be optimized.

   For more about optimization, see the GNU C documentation.


File: gpc,  Node: Debugging,  Next: Objects,  Prev: Optimization,  Up: Borland Pascal

5.8 Debugging
=============

   The command line option `-g' specifies generation of debugging
information for GDB, the GNU debugger. GDB comes with its own
documentation. Currently, GDB does not understand Pascal syntax, so you
should be familiar with C expressions if you want to use it.

   See also "Notes for debugging" in the "Programming" chapter; see
*Note Notes for Debugging::.

   Sometimes it is nice to have a look at the assembler output of the
compiler. You can do this in a debugger or disassembler (which is the
only way to do it in BP), but you can also tell GPC to produce
assembler code directly: When you specify the `-S' command line option,
GPC produces an `.s' file instead of an `.o' file.  The `.s' file
contains assembler source for your program. More about this in the next
section.


File: gpc,  Node: Objects,  Next: Strings in BP and GPC,  Prev: Debugging,  Up: Borland Pascal

5.9 Objects
===========

   Objects in the Borland Pascal 7.0 notation are implemented into GNU
Pascal with the following differences:

   * the `private', `protected', `public' and `published' directives
     are recognized but ignored,

   * data fields and methods may be mixed:
          type
            MyObj = object
              x: Integer;
              procedure Foo; virtual;
              y: Real;
              function Bar: Char;
            end;


File: gpc,  Node: Strings in BP and GPC,  Next: Typed Constants,  Prev: Objects,  Up: Borland Pascal

5.10 Strings in BP and GPC
==========================

   Strings are "Schema types" in GNU Pascal which is something more
advanced than Borland-style strings. For variables, you cannot specify
just `String' as a type like in Borland Pascal; for parameters and
pointer types you can. There is no 255 characters length limit.
According to Extended Pascal, the maximum string length must be in
(parentheses); GNU Pascal accepts [brackets], too, however, like BP.

   For more about strings and schema types see *Note Schema Types::.

   GPC supports Borland Pascal's string handling functions and some
more (see *Note String Operations::):

Borland Pascal           GNU Pascal
Length                   Length
Pos                      Pos, Index (1)
Str                      Str, WriteStr (1) (2)
Val                      Val, ReadStr (2)
Copy                     Copy, SubStr, MyStr [2 .. 7] (3)
Insert                   Insert
Delete                   Delete
MyStr [0] := #7          SetLength (MyStr, 7)
=, <>, <, <=, >, >=      =, <>, <, <=, >, >= (4)
                         EQ, NE, LT, LE, GT, GE
n/a                      Trim

   Notes:

   (1) The order of parameters of the Extended Pascal routines
(`Index', `WriteStr') is different from the Borland Pascal routines.

   (2) `ReadStr' and `WriteStr' allow an arbitrary number of arguments,
and the arguments are not limited to numbers.  `WriteStr' also allows
comfortable formatting like `WriteLn' does, e.g.  `WriteStr (Dest, Foo
: 20, Bar, 1/3 : 10 : 2)'.

   (3) `SubStr' reports a runtime error if the requested substring does
not fit in the given string, `Copy' does not (like in BP).

   (4) By default, the string operators behave like in BP. However, if
you use the option `--no-exact-compare-strings' or `--extended-pascal',
they ignore differences of trailing blanks, so, e.g., `'foo'' and `'foo
 '' are considered equal. The corresponding functions (`EQ', ...)
always do exact comparisons.


File: gpc,  Node: Typed Constants,  Next: Bit; Byte and Memory Manipulation,  Prev: Strings in BP and GPC,  Up: Borland Pascal

5.11 Typed Constants
====================

   GNU Pascal supports Borland Pascal's "typed constants" but also
Extended Pascal's initialized variables:

     var
       x : Integer value 7;

   or

     var
       x : Integer = 7;

   When a typed constant is misused as an initialized variable, a
warning is given unless you specify `--borland-pascal'.

   When you want a local variable to preserve its value, define it as
`static' instead of using a typed constant. Typed constants also become
static automatically for Borland Pascal compatibility, but it's better
not to rely on this "feature" in new programs.  Initialized variables
do not become static automatically.

     program StaticDemo;
     
     procedure Foo;
     { x keeps its value between two calls to this procedure }
     var
       x : static Integer = 0;
     begin
       WriteLn (x);
       Inc (x)
     end;
     
     begin
       Foo;
       Foo;
       Foo;
     end.

   For records and arrays, GPC supports both BP style and Extended
Pascal style initializers. When you initialize a record, you may omit
the field names. When you initialize an array, you may provide indices
with a `:'. However, this additional information is ignored completely,
so perhaps it's best for the moment to only provide the values ...

     program BPInitVarDemo;
     (*$W no-field-name-problem*) (* avoid a warning by GPC *)
     const
       A : Integer = 7;
       B : array [1 .. 3] of Char = ('F', 'o', 'o');
       C : array [1 .. 3] of Char = 'Bar';
       Foo : record
         x, y : Integer;
       end = (x : 3; y : 4);
     begin
     end.


File: gpc,  Node: Bit; Byte and Memory Manipulation,  Next: User-defined Operators in GPC,  Prev: Typed Constants,  Up: Borland Pascal

5.12 Bit, Byte and Memory Manipulation
======================================

   The bitwise operators `shl', `shr', `and', `or', `xor' and `not'
work in GNU Pascal like in Borland Pascal.  As an extension, you can
use them as procedures, for example

     program AndProcedureDemo;
     var x : Integer;
     begin
       and (x, $0000ffff);
     end.

   as an alternative to

     program AndOperatorDemo;
     var x : Integer;
     begin
       x := x and $0000ffff;
     end.

   GPC accepts the BP style notation `$abcd' for hexadecimal numbers,
but you also can use Extended Pascal notation:

     program EPBaseDemo;
     const
       Binary =  2#11111111;
       Octal  =  8#177;
       Hex    = 16#ff;
     begin
     end.

   and so on up to a basis of 36. Of course, you can mix the notations
as you like, e.g.:

     program BPEPBaseDemo;
     begin
       WriteLn ($cafe = 2#1100101011111110)
     end.

   `Inc' and `Dec' are implemented like in Borland Pascal.  `Pred' and
`Succ' are generalized according to Extended Pascal and can have a
second (optional) parameter:

     procedure SuccDemo;
     var a : Integer = 42;
     begin
       a := Succ (a, 5);
       WriteLn (a) { 47 }
     end.

   BP style `absolute' variables work in the context of overloading
other variables as well as in the context of specifying an absolute
address, but the latter is highly unportable and not very useful even
in Dos protected mode.

     program BPAbsoluteDemo;
     
     type
       TString = String (80);
       TTypeChoice = (t_Integer, t_Char, t_String);
     
     (* WARNING: BAD STYLE! *)
     procedure ReadVar (var x : Void; TypeChoice : TTypeChoice);
     var
       xInt : Integer absolute x;
       xChar : Char absolute x;
       xStr : TString absolute x;
     begin
       case TypeChoice of
         t_Integer : ReadLn (xInt);
         t_Char    : ReadLn (xChar);
         t_String  : ReadLn (xStr);
       end
     end;
     
     var
       i : Integer;
       c : Char;
       s : TString;
     
     begin
       ReadVar (i, t_Integer);
       ReadVar (c, t_Char);
       ReadVar (s, t_String);
       WriteLn (i, ' ', c, ' ', s)
     end.

   GNU Pascal knows Borland Pascal's procedures `FillChar' and `Move'.
However, their use can be dangerous because it often makes implicit
unportable assumptions about type sizes, endianness, internal
structures or similar things. Therefore, avoid them whenever possible.
E.g., if you want to clear an array of strings, don't `FillChar' the
whole array with zeros (this would overwrite the Schema discriminants,
see *Note Strings::), but rather use a `for' loop to assign the empty
string to each string. In fact, this is also more efficient than
`FillChar', since it only has to set the length field of each string to
zero.


File: gpc,  Node: User-defined Operators in GPC,  Next: Data Types in BP and GPC,  Prev: Bit; Byte and Memory Manipulation,  Up: Borland Pascal

5.13 User-defined Operators in GPC
==================================

   GNU Pascal allows the user to define operators according to the
Pascal-SC syntax:

     program PXSCOperatorDemo;
     
     type
       Point = record
         x, y : Real;
       end;
     
     operator + (a, b : Point) c : Point;
     begin
       c.x := a.x + b.x;
       c.y := a.y + b.y;
     end;
     
     var
       a, b, c : Point = (42, 0.5);
     
     begin
       c := a + b
     end.

   The Pascal-SC operators `+>', `+<', etc. for exact numerical
calculations are not implemented, but you can define them.


File: gpc,  Node: Data Types in BP and GPC,  Next: Files,  Prev: User-defined Operators in GPC,  Up: Borland Pascal

5.14 Data Types in BP and GPC
=============================

   * Integer types have different sizes in Borland and GNU Pascal:

     Borland Pascal      GNU Pascal         Bits (1)     Signed
     ShortInt            ByteInt             8           yes
     Integer             ShortInt           16           yes
     LongInt             Integer            32           yes
     Comp                LongInt, Comp      64           yes
     Byte                Byte                8           no
     Word                ShortWord          16           no
     n/a                 Word               32           no
     n/a                 LongWord           64           no

     (1) The size of the GNU Pascal types may depend on the platform.
     The sizes above apply to 32 bit platforms, including the x86.

     If you care for types with exactly the same size as in Borland
     Pascal, take a look at the `System' unit and read its comments.

     You can get the size of a type with `SizeOf' in bytes (like in
     Borland Pascal) and with `BitSizeOf' in bits, and you can declare
     types with a specific size (given in bits), e.g.:

          program IntegerSizeDemo;
          type
            MyInt  = Integer (42);  { 42 bits, signed }
            MyWord = Word (2);      { 2 bits, unsigned, i.e., 0 .. 3 }
            MyCard = Cardinal (2);  { the same }
          
            HalfInt = Integer (BitSizeOf (Integer) div 2);
              { A signed integer type which is half as big as the normal
                `Integer' type, regardless of how big `Integer' is
                on any platform the program is compiled on. }
          
          begin
          end.

   * Borland's Real types are supported except for the 6-byte software
     Real (but the `System' unit provides conversion routines for
     them). GNU Pascals's `Real' type has 8 bytes on the x86 and is the
     same as `Double'. In addition there are alternative names for real
     types:

     Borland Pascal      GNU Pascal
     Single              Single, ShortReal
     Real                n/a (1)
     Double              Double, Real
     Extended            Extended, LongReal
     Comp                LongInt, Comp (see above)

     (1) But see `BPReal', `RealToBPReal' and `BPRealToReal' in GPC's
     `System' unit.

   * Complex numbers: According to Extended Pascal, GNU Pascal has
     built-in complex numbers and supports a number of mathematical
     functions on them, e.g. `Abs', `Sqr', `SqRt', `Exp', `Ln', `Sin',
     `Cos', `ArcTan'.

   * Record types: GNU Pascal by default aligns 32-bit fields on 4-byte
     addresses because this improves performance. So, e.g., the record
          type
            MyRec = record
              f, o, oo : Boolean;
              Bar : Integer
            end;
     has 8 bytes, not 7. Use the `--pack-struct' option or declare the
     record as `packed' to force GPC to pack it to 7 bytes.  However,
     note that this produces somewhat less efficient code on the x86
     and far less efficient code on certain other processors. Packing
     records and arrays is mostly useful only when using large
     structures where memory usage is a real concern, or when reading
     or writing them from/to binary files where the exact layout
     matters.

   * In addition to BP's procedural types, GNU Pascal has pointers to
     procedures:

          type
            FuncPtr = ^function (Real) : Real;

     GNU Pascal also supports Standard Pascal's procedural parameters -
     see below.

     Furthermore, GNU Pascal allows you to call local procedures through
     procedural pointers, variables or parameters without reverting to
     any dirty tricks (like assembler, which is necessary in Borland
     Pascal).



File: gpc,  Node: Files,  Next: Built-in Constants,  Prev: Data Types in BP and GPC,  Up: Borland Pascal

5.15 Files
==========

   * GPC supports files like in Borland Pascal, including untyped files,
     `BlockRead', `BlockWrite' and `Assign'. Instead of `Assign', you
     can also use the `Bind' mechanism of Extended Pascal.

     Besides the routines supproted by BP, there are many more routines
     available that deal with files, file names and similar things in a
     portable way. In contrast to Borland Pascal, you don't have to use
     any platform-specific units to do these kinds of things, though
     portable emulations of those units (e.g., of the `Dos' and
     `WinDos' units) are also available for compatibility.



File: gpc,  Node: Built-in Constants,  Next: Built-in Operators in BP and GPC,  Prev: Files,  Up: Borland Pascal

5.16 Built-in Constants
=======================

   * The `MaxInt', `MaxLongInt', `Pi' constants are supported like in
     BP.

   * Other built-in constants: GNU Pascal has `MaxChar', `MaxReal',
     `MinReal', `EpsReal' and a number of other useful constants.


File: gpc,  Node: Built-in Operators in BP and GPC,  Next: Built-in Procedures and Functions,  Prev: Built-in Constants,  Up: Borland Pascal

5.17 Built-in Operators in BP and GPC
=====================================

   Besides the operators found in Borland Pascal, GNU Pascal supports
the following operators:

   * Exponentiation: According to Extended Pascal, GNU Pascal supports
     the exponentiation operators `pow' and `**' which do not exist in
     Borland Pascal. You can use `x pow y' for integer and `x ** y' for
     real or complex exponents. The basis may be integer, real or
     complex in both cases.

   * Address operator: GNU Pascal accepts Borland's `@', but also `&'
     as an address operator.

   * GNU Pascal has a symmetric set difference operator `set1 >< set2'.
     For more about this, see *Note Set Operations::.


File: gpc,  Node: Built-in Procedures and Functions,  Next: Special Parameters,  Prev: Built-in Operators in BP and GPC,  Up: Borland Pascal

5.18 Built-in Procedures and Functions
======================================

   * `GetMem' and `FreeMem' are supported like in BP.  `GetMem' can
     also act as a function in GNU Pascal:

          program GetMemFunctionDemo;
          var p : Pointer;
          begin
            p := GetMem (1024)
          end.

     The second parameter to `FreeMem' is ignored by GNU Pascal and may
     be omitted. Memory blocks are always freed with the same size they
     were allocated with.

     Remark: Extended Pascal Schema types provide a cleaner approach to
     most of the applications of `GetMem' and `FreeMem'.

   * `Min' and `Max': GNU Pascal has built-in `Min' and `Max' functions
     (two arguments) which work for all ordinal types (`Integer',
     `Char', ...) plus `Real'.

   * `UpCase', `High', `Low' and similar functions are built-in. In
     contrast to Borland Pascal, GNU Pascal's `UpCase' function is
     aware of non-ASCII characters of certain languages (e.g., accented
     letters and "umlauts"), but for compatibility this feature is
     disables in `--borland-pascal' mode. There is also a `LoCase'
     function.

   * `Lo', `Hi', `Swap' functions: not built-in, but available in the
     `System' unit.


File: gpc,  Node: Special Parameters,  Next: Miscellaneous,  Prev: Built-in Procedures and Functions,  Up: Borland Pascal

5.19 Special Parameters
=======================

   * Untyped reference parameters can be denoted by

          procedure Foo (var x);

     like in Borland Pascal. In GNU Pascal, you can also use

          procedure Foo (var x : Void);

   * GNU Pascal defines "ellipsis" parameters for variable argument
     lists:

          procedure Foo (a : Integer; ...);

     However, GPC does not (yet) provide a portable mechanism to access
     the additional arguments.

   * Structured function return values: According to Extended Pascal,
     GNU Pascal allows functions to return records and arrays.

   * BP style "open array parameters"
          procedure Foo (a : array of Integer);
     are implemented. However, Standard Pascal `conformant array
     parameters' are usually a cleaner mechanism to pass arrays of
     variable size.

   * Besides BP compatible procedural types, GNU Pascal supports
     Standard Pascal's procedural parameters:

          procedure DrawGraph (function f (x : Real) : Real);


File: gpc,  Node: Miscellaneous,  Next: BP and Extended Pascal,  Prev: Special Parameters,  Up: Borland Pascal

5.20 Miscellaneous
==================

   * Headlines: According to Extended Pascal, a program headline must
     contain the program's parameters:

          program Foo (Input, Output);
          begin
          end.

     In GNU Pascal, headline parameters are optional. If the headline is
     omitted entirely, a warning is given unless you have specified
     `--borland-pascal' in the command line.

   * `case' statements: In a `case' statement, GNU Pascal allows
     `otherwise' (according to Extended Pascal) as an alternative to
     `else':

          program CaseOtherwiseDemo;
          var x : Integer;
          begin
            ReadLn (x);
            case x of
              1 : WriteLn ('one');
              2 : WriteLn ('two');
              otherwise
                WriteLn ('many')
            end
          end.

     Note: In the absence of a `case' or `otherwise' branch, missing
     cases labels cause an error in Extended Pascal (which goes
     unnoticed in Borland Pascal). GPC does not give this error, but a
     warning if the `-Wswitch' option is given, however only for
     enumeration types.

   * Character constants: BP compatible character constants like `^M'
     as well as `#13' are implemented into GNU Pascal.

   * Sets: GNU Pascal has a `Card' function for sets which counts their
     elements. Unlike Borland Pascal, GNU Pascal does not limit sets to
     the range 0 .. 255.

   * Inline: GNU Pascal allows "inline" Pascal procedures and
     functions, while Borland Pascal only allows machine code to be
     inlined:

     Borland Pascal:

          function Max (x, y : Integer) : Integer;
            inline ($58 / $59 / $3b / $c1 / $7f / $01 / $91);

     GNU Pascal:

          program InlineDemo;
          
          inline function Max (x, y : Integer) : Integer;
          begin
            if x > y then
              Max := x
            else
              Max := y
          end;
          
          begin
            WriteLn (Max (42, 17), ' ', Max (-4, -2))
          end.

     (Actually, a more general `Max' function is already built-in.)

     This feature is not so important as it might seem because in
     optimization level 3 or higher (*note GPC Options::), GNU Pascal
     automatically inlines short procedures and functions.


File: gpc,  Node: BP and Extended Pascal,  Next: Portability hints,  Prev: Miscellaneous,  Up: Borland Pascal

5.21 BP and Extended Pascal
===========================

   Pascal is a well-known programming language and hardly needs to be
described here. Note, however, that there is a large difference between
the language used by the BP compiler and the Pascal Standards.

   Extended Pascal is a standardized language based on the original
Standard Pascal, but with significant extensions. Unfortunately,
Borland Pascal does not conform to any of the Pascal standards.
Writing a program that both complies to Extended Pascal (or even
Standard Pascal) and compiles with BP is almost impossible for any
non-trivial task.

   On the other hand, BP has some nice features that make it very
powerful in the environments in which it runs. However, some of those
features are of little use on non-Dos systems and would not be good
candidates for standardization.

   There are also several BP features which are semantically similar to
features in Standard Pascal or Extended Pascal, but syntactically
different.

   Therefore, in order to be useful to users coming from either side,
GPC supports both the standards and the BP dialect as good as possible.
By default, GPC allows features from any dialect it knows.  By giving a
dialect option such as `--borland-pascal' or `--extended-pascal', you
can tell GPC to disable the features not found in that dialect, and to
adjust its warning behaviour to the dialect.

   The different sets of reserved words are a little problem, but GPC
solves it by making the words in question only "conditionally reserved"
which works transparently without problems in most cases. Still, giving
a dialect option will disable all keywords not part of this dialect.

   Apart from this, there are surprisingly few real conflicts between
the dialects. Therefore, you can usually compile your BP code without
the `--borland-pascal' option and make use of all of GPC's features.
You might be surprised, though, when GPC accepts things you didn't know
were allowed. :-)

   Finally, if you want to make use of some of GPC's extensions
(compared to BP) and still keep the code compileable with BP without
using `ifdef's all over the place, we suggest you look at the unit
`gpc-bp.pas', shipped with GPC, which contains BP versions of some of
GPC's features. Please read the comments at the beginning of the unit
to find out more about it.


File: gpc,  Node: Portability hints,  Prev: BP and Extended Pascal,  Up: Borland Pascal

5.22 Portability hints
======================

   GPC offers you the possibility to make your code fully portable to
each of the many platforms supported by GPC. It would be a pity not to
make use of this.

   This section lists some known pitfalls that often hinder otherwise
well-written programs to take full advantage of GPC. If you have never
used any compiler but Borland Pascal and similar compilers, some of the
advices might look strange to you. But this is just the same level of
strangeness that your old programs will have for you once you have
understood the principles of cross-platform portability. Remember that
many tricks you have always been applying almost automatically in
Borland Pascal were necessary to overcome certain limitations of the
Dos platform and to compensate for the compiler's missing optimization.
Programming with an optimizing compiler like GPC for platforms without
a 64 kB limit is a completely new experience - and perhaps it is among
the reasons why you are now working with GPC in the first place?

Portability - why?
------------------

   _Okay - but why should I bother and make my program portable?  I
know that all who want to use my program are running WXYZ-OS anyway._

   Yes, but that's the result of a self-fulfilling prophecy. It depends
on *you* whether it will always remain like this or not.  Consider a
program ABC written for a single platform, WXYZ-OS.  Naturally, only
WXYZ-OS-users get interested in ABC. The author gets feedback only from
WXYZ-OS users and does not see any reason to make the program
cross-platform. Then people realize that if they want to run ABC they
must move to WXYZ-OS. The author concludes that people only want
WXYZ-OS programs, and so on.

   To break out, just create a portable version of your program *now*.
Then all OSes have equal chances to show their abilities when running
your program, and your customers can choose their OS. Then, maybe, they
decide to use your program just for the reason that they can be sure
that it will run on all present and future platforms and not only on a
specific one - who knows?

   _My program is a tool specifically designed to make the best of the
STUV feature of WXYZ-OS. There is no point in making it portable._

   How much do you know about non-WXYZ-OSes? Just ask an expert how the
STUV feature is named elsewhere. Be sure, if it is of value, it exists
almost everywhere.

Low-level features
==================

   _I am using a lot of low-level stuff in my programs, so they cannot
be portable._

   You do not use those low-level routines directly in your high-level
routines, do you? There should always be a layer "in-between" that
encapsulates the low-level routines and present an API to your program
that exactly reflects the needs of your application.  This "API in
between" is the point where you can exchange the low-level routines by
portable calls to GPC's Run Time System.

   If you do not have such a layer in-between, then the API of the
low-level routines you call are your first approximation for such a
layer.  If you have ever thought "it would be great if that API
function had that additional parameter", then your own extended version
of that API function that *has* that parameter can become part of your
"API in between".  But then don't stop here: Certainly the API of the
OS is *not* ideal for your program's needs. Just create more routines
that encapsulate all OS-specific stuff ...

   When the low-level stuff in question consists of interrupts,
assembler and similar things, then the first thing you need is a
portable replacement of the functionality. Fortunately, GPC covers many
things already in Pascal that require assembler in Borland Pascal:

   * GPC's libraries come with source. You do not need to learn
     assembler and to write a complete replacement for the CRT unit if
     you only want to adapt some tiny detail in the behavior of CRT to
     your personal needs.

   * GPC's Run Time System is fairly complete. For example, to extract
     the assigned name of a `File' variable, you do not need to mess
     around with the internal representation of those variables, but you
     can type `uses GPC' and then use the `FileName' function.  In the
     same unit, you will find a `FileExists' function and much more.

   * Manually "constructing" an object is covered by the `SetType'
     procedure in GPC. This is where Turbo Vision uses assembler to load
     an object from a stream.

   * Calling local procedures and functions via pointers simply works in
     GPC. This is another place where, for instance, Turbo Vision's
     `ForEach' method uses assembler, while GPC lets you do the same
     thing in Pascal.

   * Interfacing with the OS can be done through library calls. GPC's
     built-in functions and the GPC unit offer a rather complete set of
     routines. And again: You have the source of all this.

   * Using `FillChar' and `Move' does not necessarily speed up your
     programs. Using them to circumvent restrictions of the language
     (e.g. for direct assignments between variables of object or file
     type) is asking for trouble. `FillChar' was created in UCSD Pascal
     to set consecutive chars in a string to the same value, and `Move'
     was created to move the chars within the same string.  Better do
     not use them for other purposes.



File: gpc,  Node: Invoking GPC,  Next: Programming,  Prev: Borland Pascal,  Up: Top

6 Command Line Options supported by GNU Pascal.
***********************************************

   GPC is a command-line compiler, i.e., to compile a program you have
to invoke `gpc' passing it the name of the file you want to compile,
plus options.

   GPC supports all command-line options that GCC knows. For a complete
reference and descriptions of all options, see *Note GCC Command
Options: (gcc)Invoking GCC.  Below, you will find a list of the
additional options that GPC supports, and a list of GPC's most
important options (including some of those supported by GCC as well).

   You can mix options and file names on the command line. For the most
part, the order doesn't matter. Order does matter, e.g., when you use
several options of the same kind; for example, if you specify `-L' more
than once, the directories are searched in the order specified. _Note:_
Since many options have multiletter names; multiple single-letter
options may _not_ be grouped as is possible with many other programs:
`-dr' is very different from `-d -r'.

   Many options have long names starting with `--' or, completely
equivalent `-f'. E.g., `--mixed-comments' is the same as
`-fmixed-comments'. Some options tell GPC when to give warnings, i.e.
diagnostic messages that report constructs which are not inherently
erroneous but which are risky or suggest there may have been an error.
Those options start with `-W'.

   Most GPC specific options can also be changed during one compilation
by using compiler directives in the source, e.g. `{$X+}' or
`{$extended-syntax}' for `--extended-syntax' (*note Compiler
Directives::).

   GPC understands the same environment variables GCC does (*note
Environment Variables Affecting GCC: (gcc)Environment Variables.).  In
addition, GPC recognizes `GPC_EXEC_PREFIX' with the same meaning that
`GCC_EXEC_PREFIX' has to GCC. GPC also recognizes `GCC_EXEC_PREFIX',
but `GPC_EXEC_PREFIX' takes precedence.

* Menu:

* GPC Command Line Options::  GPC options besides those of GCC.
* GPC Options::               The most commonly used options to GPC.


File: gpc,  Node: GPC Command Line Options,  Next: GPC Options,  Up: Invoking GPC

6.1 GPC options besides those of GCC.
=====================================

   The following table lists the command line options GPC understands
in addition to those understood by GCC.

`--standard-pascal-level-0'
     Reject conformant arrays and anything besides ISO-7185 Standard
     Pascal.

`--standard-pascal'
     Reject anything besides ISO-7185 Standard Pascal.

`--extended-pascal'
     Reject anything besides ISO-10206 Extended Pascal.

`--object-pascal'
     Reject anything besides (the implemented parts of) ANSI draft
     Object Pascal.

`--borland-pascal'
     Try to emulate Borland Pascal, version 7.0.

`--delphi'
     Try to emulate Borland Pascal, version 7.0, with some Delphi
     extensions.

`--pascal-sc'
     Be strict about the implemented Pascal-SC extensions.

`--gnu-pascal'
     Undo the effect of a previous `--foo-pascal', `--delphi' or
     `--pascal-sc' switch.

`--lines'
     (Unimplemented switch for debugging).

`--debug-tree'
     (Internal directive for debugging the compiler).

`--debug-gpi'
     (Internal directive for debugging the compiler).

`--debug-source'
     (Internal directive for debugging the compiler).

`--progress-messages'
     Output source file names and line numbers while compiling.

`--progress-bar'
     Output number of processed lines while compiling.

`--autolink'
     Automatically link object files provided by units/modules or `{$L
     ...}' (default).

`--no-autolink'
     Do not automatically link object files provided by
     units/modules/`{$L ...}'.

`--automake'
     Automatically compile changed units/modules/`{$L ...}' files and
     link the object files provided.

`--no-automake'
     Same as `--no-autolink'.

`--autobuild'
     Automatically compile all units/modules/`{$L ...}' files and link
     the object files provided.

`--no-autobuild'
     Same as `--no-autolink'.

`--amtmpfile'
     (Internal switch used for AutoMake).

`--extended-syntax'
     Enable certain `dangerous' features such as ignoring function
     results, pointer arithmetic or using `CString's as strings (same
     as `{$X+}').

`--no-extended-syntax'
     Disable the dangerous features enabled by `--extended-syntax'
     (default; same as `{$X-}').

`--signed-char'
     Let `Char' be a signed type.

`--no-signed-char'
     Let `Char' be an unsigned type.

`--unsigned-char'
     Let `Char' be an unsigned type.

`--no-unsigned-char'
     Let `Char' be a signed type.

`--short-circuit'
     Guarantee short-circuit Boolean evaluation (default; same as
     `{$B-}').

`--no-short-circuit'
     Do not guarantee short-circuit Boolean evaluation (same as
     `{$B+}').

`--mixed-comments'
     Allow comments like `{ ... *)' as required in ISO Pascal (default
     in Standard Pascal mode).

`--no-mixed-comments'
     Ignore `{' and `}' within `(* ... *)' comments and vice versa
     (default).

`--nested-comments'
     Allow nested comments like `{ { } }' and `(* (* *) *)'.

`--no-nested-comments'
     Do not allow nested comments (default).

`--delphi-comments'
     Allow Delphi style `//' comments (default).

`--no-delphi-comments'
     Do not allow Delphi style `//' comments.

`--macros'
     Expand macros (default).

`--no-macros'
     Do not expand macros (default with `--borland-pascal' or
     `--delphi').

`--ignore-function-results'
     Do not complain when a function is called like a procedure.

`--no-ignore-function-results'
     Complain when a function is called like a procedure (default).

`--borland-char-constants'
     Allow for Borland-style character constants like `#27' or `^L'
     (default).

`--no-borland-char-constants'
     Reject Borland-style character constants like `#27' or `^L'
     (default in Standard Pascal mode).

`--truncate-strings'
     Truncate strings being assigned to other strings of too short
     capacity..

`--no-truncate-strings'
     Treat string assignments to other strings of too short capacity as
     errors..

`--exact-compare-strings'
     Do not blank-pad strings for comparisons.

`--no-exact-compare-strings'
     Blank-pad strings for comparisons.

`--io-checking'
     Do automatic run-time checks after I/O operations (same as
     `{$I+}').

`--no-io-checking'
     Do not check I/O operations automatically (same as `{$I-}').

`--write-clip-strings'
     In write statements, truncate strings exceeding their field width
     (`Write (SomeLongString : 3)').

`--no-write-clip-strings'
     Do not truncate strings exceeding their field width.

`--write-real-blank'
     Output a blank in front of positive reals in exponential form
     (default).

`--no-write-real-blank'
     Do not output a blank in front of positive reals in exponential
     form.

`--write-capital-exponent'
     Write real exponents with a capital `E'.

`--no-write-capital-exponent'
     Write real exponents with a lowercase `e'.

`--transparent-file-names'
     Derive external file names from variable names.

`--no-transparent-file-names'
     Do not derive external file names from variable names (default).

`--field-widths'
     Comma-separated list of default field widths for Integer, Real,
     Boolean, LongInt, LongReal.

`--no-field-widths'
     Reset the default field widths.

`--pedantic'
     Warn about everything rejected in some dialect, e.g. redefinition
     of its keywords.

`--no-pedantic'
     Don't give pedantic warnings.

`--stack-checking'
     Enable stack checking (same as `{$S+}').

`--no-stack-checking'
     Disable stack checking (same as `{$S-}').

`--typed-address'
     Make the result of the address operator typed (same as `{$T+}',
     default).

`--no-typed-address'
     Make the result of the address operator an untyped pointer (same
     as `{$T-}').

`--setlimit'
     Define the range for `set of Integer' etc..

`--gpc-main'
     External name for the program's entry point (default: `main').

`--interface-only'
     Compile only the interface part of a unit/module and exit.

`--implementation-only'
     Do not produce a GPI file; only compile the implementation part.

`--executable-file-name'
     Name for the output file, if specified; otherwise derive from main
     source file name.

`--unit-path'
     Directories where to look for unit/module sources.

`--no-unit-path'
     Forget about directories where to look for unit/module sources.

`--object-path'
     Directories where to look for additional object (and source) files.

`--no-object-path'
     Forget about directories where to look for additional object (and
     source) files.

`--executable-path'
     Path where to create the executable file.

`--no-executable-path'
     Create the executable file in the directory where the main source
     is (default).

`--unit-destination-path'
     Path where to create object and GPI files.

`--no-unit-destination-path'
     Create object and GPI files in the current directory (default).

`--object-destination-path'
     Path where to create additional object files.

`--no-object-destination-path'
     Create additional object files in the current directory (default).

`--no-default-paths'
     Do not add a default path to the unit and object path.

`--gpi-destination-path'
     (Internal switch used for AutoMake).

`--uses'
     Add an implicit `uses' clause.

`--cidefine'
     Define a case-insensitive macro.

`--csdefine'
     Define a case-sensitive macro.

`-Wwarnings'
     Enable warnings (same as `{$W+}').

`-Wno-warnings'
     Disable warnings (same as `{$W-}').

`-Wfield-name-problem'
     Warn about ignored field names in initializers (default).

`-Wno-field-name-problem'
     Do not warn about ignored field names in initializers.

`-Wobject-directives'
     Warn about unimplemented `private', `protected' and `public'
     directives (default).

`-Wno-object-directives'
     Do not warn about unimplemented `private', `protected' and
     `public' directives.

`-Wtyped-const'
     Warn about misuse of typed constants as initialized variables
     (default).

`-Wno-typed-const'
     Do not warn about misuse of typed constants as initialized
     variables.

`-Wnear-far'
     Warn about use of useless `near' or `far' directives (default).

`-Wno-near-far'
     Do not warn about use of useless `near' or `far' directives.

`-Wunderscore'
     Warn about double/leading/trailing underscores in identifiers.

`-Wno-underscore'
     Do not warn about double/leading/trailing underscores in
     identifiers.

`-Wmixed-comments'
     Warn about mixed comments like `{ ... *)'.

`-Wno-mixed-comments'
     Do not warn about mixed comments.

`-Wnested-comments'
     Warn about nested comments like `{ { } }'.

`-Wno-nested-comments'
     Do not warn about nested comments.


File: gpc,  Node: GPC Options,  Prev: GPC Command Line Options,  Up: Invoking GPC

6.2 The most commonly used options to GPC
=========================================

   As the most simple example, calling

     gpc foo.pas

   tells GPC to compile the source file `foo.pas' and to produce an
executable of the default name which is `foo.exe' on EMX, `a.exe' on
DJGPP, and `a.out' on most other platforms.

   Users familiar with BP, please note that you have to give the file
name extension `.pas': GPC is a common interface for a Pascal compiler,
a C, ObjC and C++ compiler, an assembler, a linker, and perhaps an Ada
and a FORTRAN compiler. From the extension of your source file GPC
figures out which compiler to run. GPC recognizes Pascal sources by the
extension `.pas', `.p', `.pp' or `.dpr'. GPC also accepts source files
in other languages (e.g., `.c' for C) and calls the appropriate
compilers for them. Files with the extension `.o' or without any special
recognized extension are considered to be object files or libraries to
be linked.

   Another example:

     gpc -O2 -Wall --executable-file-name --automake --unit-path=units foo.pas

   This will compile the source file `foo.pas' to an executable named
`foo' (`--executable-file-name') with fairly good optimization (`-O2'),
warning about possible problems (`-Wall'). If the program uses units or
imports modules, they will be searched for in a directory called `units'
(`--unit-path') and automatically compiled and linked (`--automake').

   The following table lists the most commonly used options to GPC.

`--automake'
     Check whether modules/units used must be recompiled and do the
     recompilation when necessary.

`--unit-path=DIR[:DIR...]'
     Search the given directories for units and object files.

`--object-path=DIR[:DIR...]'
     Search the given directories for object files.

`--unit-destination-path=DIR'
     Place units compiled into the directory DIR. The default is the
     current directory.

`--object-destination-path=DIR'
     Place object files compiled into the directory DIR. The default is
     the directory given with `--unit-destination-path'.

`--executable-path=DIR'
     Place the executable compiled into the directory DIR. The default
     is the main source file's directory.

`-o FILE'
     Place output in file FILE. This applies regardless to whatever
     sort of output is being produced, whether it be an executable file,
     an object file, an assembler file, etc.

     Since only one output file can be specified, it does not make sense
     to use `-o' when compiling more than one input file, unless you
     are producing an executable file as output.

`--executable-file-name[=NAME]'
     Derive the executable file name from the source file name, or use
     NAME as the executable file name. The difference to the `-o'
     option is that `--executable-file-name' considers the
     `--executable-path', while `-o' does not and accepts a file name
     with directory. Furthermore, `--executable-file-name' only applies
     to executables, not to other output formats selected.

`-LDIR'
     Search the directory DIR for libraries. Can be given multiple
     times.

`-IDIR'
     Search the directory DIR for include files. Can be given multiple
     times.

`-lLIBRARY'
     Search the library named LIBRARY when linking. This option must be
     placed on the command line _after_ all source or object files or
     other libraries that reference the library.

`-O[N]'
     Select the optimization level. Without optimization (or `-O0'
     which is the default), the compiler's goal is to reduce the
     compilation time and to make debugging produce the expected
     results.  Statements are independent: if you stop the program with
     a breakpoint between statements, you can then assign a new value to
     any variable or change the program counter to any other statement
     in the same routine and get exactly the results you would expect
     from the source code.

     With optimization, the compiler tries to reduce code size and
     execution time. The higher the value of N, the more optimizations
     will be done, but the longer the compilation will take.

     If you use multiple `-O' options, with or without N, the last such
     option is the one that is effective.

`-g'
     Produce debugging information suitable for `gdb'. Unlike some
     other compilers, GNU Pascal allows you to use `-g' with `-O'. The
     shortcuts taken by optimized code may occasionally produce
     surprising results: some variables you declared may not exist at
     all; flow of control may briefly move where you did not expect it;
     some statements may not be executed because they compute constant
     results or their values were already at hand; some statements may
     execute in different places because they were moved out of loops.
     Nevertheless it proves possible to debug optimized output. This
     makes it reasonable to use the optimizer for programs still in the
     testing phase.

`-s'
     Remove all symbol table and relocation information from the
     executable. Note: this has no influence on the performance of the
     compiled executable.

`-Wall'
     Give warnings for a number of constructs which are not inherently
     erroneous but which are risky or suggest there may have been an
     error. There are additional warning options not implied by
     `-Wall', see the GCC warning options (*note Options to Request or
     Suppress Warnings: (gcc)Warning Options.), while `-Wall' only
     warns about such constructs that should be easy to avoid in
     programs. Therefore, we suggest using `-Wall' on most sources.

`-Werror'
     Turn all warnings into errors.

`-S'
     Stop after the stage of compilation proper; do not assemble. The
     output is in the form of an assembler code file for each source
     file. By default, the assembler file name for a source file is made
     by replacing the extension with `.s'.

`-c'
     Compile and assemble the source files, but do not link. The output
     is in the form of an object file for each source file. By default,
     the object file name for a source file is made by replacing the
     extension with `.o'.

`-static'
     On systems that support dynamic linking, this prevents linking with
     the shared libraries, i.e. forces static linking. On other systems,
     this option has no effect.

`-DMACRO[=DEFN]'
     Define the macro and conditional MACRO as DEFN (or as `1' if DEFN
     is omitted).

`-b MACHINE'
     The argument MACHINE specifies the target machine for compilation.
     This is useful when you have installed GNU Pascal as a
     cross-compiler.

`-v'
     Print (on standard error) the commands executed to run the stages
     of compilation. Also print the version number of the compiler
     driver program and of the preprocessor and the compiler proper.

`--standard-pascal-level-0'
`--standard-pascal'
`--extended-pascal'
`--object-pascal'
`--borland-pascal'
`--pascal-sc'
     GNU Pascal supports the features of several different Pascal
     standards and dialects. By default, they are all enabled. These
     switches tell GPC to restrict itself to the features of the
     specified standard. It does not enable any additional features.
     Warnings about constructs which would be legal in the specified
     dialect (e.g. assignment to a typed constant with
     `--borland-pascal') are suppressed.

     By default, GNU Pascal allows redefinition of keywords. Each of
     these switches causes GNU Pascal to forbid the redefinition of
     keywords of the specified standard.

     Valid ISO Standard Pascal programs should compile properly with or
     without `--standard-pascal'. However, without this option, certain
     GNU extensions and Pascal features from other dialects are
     supported as well. With this option, they are rejected.

     These options are not intended to be useful; they exist only to
     satisfy pedants who would otherwise claim that GNU Pascal fails to
     support the ISO Standard or is not really compatible to Borland
     Pascal, or whatever. We recommend, rather, that users take
     advantage of the extensions of GNU Pascal and disregard the
     limitations of other compilers.

`-pedantic-errors'
     Produce errors rather than warnings for portability violations.
     Unlike in C, this does _not_ imply the `-pedantic' option, so you
     can, for instance, use `-pedantic-errors' without `-pedantic', but
     with `--extended-pascal'.

`--gpc-main=NAME'
     Name the entry point of the main program `NAME' instead of `main'
     on the linker level. This is useful, e.g., when working with some
     C libraries which define their own `main' function and require the
     program's main entry point to be named differently.


File: gpc,  Node: Programming,  Next: Reference,  Prev: Invoking GPC,  Up: Top

7 The Programmer's Guide to GPC
*******************************

   *This chapter is still under development.*

   This chapter tells you how the source of a valid GNU Pascal program
should look like.  You can use it as tutorial about the GNU Pascal
language, but since the main goal is to document all special GPC
features, implementation-dependent stuff, etc., expect a steep learning
curve.

   This chapter does _not_ cover how to compile your programs and to
produce an executable - this is discussed above in *Note Invoking GPC::.

* Menu:

* Source Structures::            Programs, Units and Modules.
* Data Types::                   Standard and non-standard data types.
* Operators::                    Built-in and user-definable operators.
* Parameters::                   Procedure And Function Parameters
* Pointer Arithmetics::          How pointer arithmetics works in Pascal.
* Type Casts::                   Explicit and emulated type casting in GPC.
* OOP::                          How object-orientated programming is implemented.
* Compiler Directives::          Compiler Directives And The Preprocessor
* Library Routines::             Routines Built-in or in the Run Time System
* Other Languages::              How to share libraries with other languages.
* Notes for Debugging::          Problems and caveats when debugging GPC programs.
* Run Time System::              Pascal declarations for GPC's Run Time System library.
* GPC Units::                    Units included with GPC


File: gpc,  Node: Source Structures,  Next: Data Types,  Up: Programming

7.1 Source Structures
=====================

   A source file accepted by GNU Pascal may contain up to one program,
zero or more ISO-style modules, and/or zero or more UCSD-style units.
Units and modules can be mixed in one project.

* Menu:

* The Program::                 The Source Structure of Programs
* Label Declaration::
* Constant Declaration::
* Type Declaration::
* Variable Declaration::
* Subroutine Declaration::      Procedures, Functions and Operators
* Statements::                  Loops and Conditional Statements
* Modules and Units::           Import Part and Module/Unit Concept

   One trivial example for a valid GPC source file follows. Note that
the code below may either be in one source file, or else the unit and
the program may be in separate source files.

     unit DemoUnit;
     
     interface
     
     procedure Hello;
     
     implementation
     
     procedure Hello;
     begin
       WriteLn ('Hello, world!')
     end;
     
     end.
     
     program UnitDemo;
     
     uses
       DemoUnit;
     
     begin
       Hello
     end.


File: gpc,  Node: The Program,  Next: Label Declaration,  Up: Source Structures

7.1.1 The Source Structure of Programs
--------------------------------------

   A generic GNU Pascal program looks like the following:

     program NAME (Input, Output);
     
     IMPORT PART
     
     DECLARATION PART
     
     begin
       STATEMENT PART
     end.

   The `program' headline may be omitted in GPC, but a warning will be
given except in `--borland-pascal' mode.

   While the program parameters (usually `Input', `Output') are
obligatory in ISO Pascal if you want to use `ReadLn' and `WriteLn',
they are optional in GNU Pascal. GPC will warn about such missing
parameters in `--extended-pascal' mode. However if you give parameters
to the program headline, they work like ISO requires.

   The IMPORT PART consists either of an ISO-style `import'
specification or a UCSD/Borland-style `uses' clause. While `import' is
intended to be used with interfaces exported by ISO-10206 Extended
Pascal modules, and `uses' is intended to be used with units, this is
not enforced. (See also *Note uses::, *Note import::.)

   The DECLARATION PART consists of label, constant, type, variable or
subroutine declarations in free order. However, every identifier must
be declared before it is used. The only exception are type identifiers
pointing to another type identifier which may be declared below.

   The STATEMENT PART consists of a sequence of statements.

   As an extension, GPC supports a "declaring statement" which can be
used in the statement part to declare variables (see *Note var::).


File: gpc,  Node: Label Declaration,  Next: Constant Declaration,  Prev: The Program,  Up: Source Structures

7.1.2 Label Declaration
-----------------------

   A label declaration has the following look:

     label
       LABEL NAME, ..., LABEL;

   A label declaration part starts with the reserved word `label',
which contains a list of labels.


   *See also* *Note label::, *Note goto::


File: gpc,  Node: Constant Declaration,  Next: Type Declaration,  Prev: Label Declaration,  Up: Source Structures

7.1.3 Constant Declaration
--------------------------

   A constant declaration has the following look:

     const
       CONSTANT IDENTIFIER = CONSTANT EXPRESSION;
       ...
       CONSTANT IDENTIFIER = CONSTANT EXPRESSION;

   A constant declaration part starts with the reserved word `const'.
It declares a CONSTANT IDENTIFIER which is defined by CONSTANT
EXPRESSION. This expression has to be evaluatable during compilation
time, i.e. it can include numbers, parentheses, predefined operators,
sets and type casts (the last, however, is a Borland extension).  In
ISO-7185 Pascal, CONSTANT EXPRESSION must be a constant or a set. All
Pascal Dialects but ISO-Pascal allow the use of these intrinsic
functions in CONSTANT EXPRESSION:

   *Note Abs::, *Note Round::, *Note Trunc::,

   *Note Chr::, *Note Ord::,

   *Note Length::, *Note Pred::, *Note Succ::,

   *Note SizeOf::, *Note Odd::.

   In Borland Pascal, in the constant declaration part variables can be
declared as well, which are given an initial value. These variables are
called "typed constants". It is good style to avoid this use,
especially since Extended Pascal and GNU Pascal allow to initialize a
variable in variable declaration part or give a type a preset value on
declaration.

     const
       FiveFoo      = 5;
       StringFoo    = 'string constant';
       AlphabetSize = Ord ('Z') - Ord ('A') + 1;
     
     type
       PInteger     = ^Integer;     { Define a pointer to an Integer }
     
     const
       { Constant which holds a pointer to an Integer at address 1234 }
       AddressFoo   = PInteger (1234);

   * BP does not know initialized variables, only typed constants. Even
     worse, it allows them to be misused as variables, without even
     warning. GPC supports this (unwillingly ;-), and warns unless in
     `--borland-pascal' mode.

     An example of a typed constant:

          const
            i : Integer = 0;

     If you want to use it as a constant only, that's perfectly fine.
     However, if you modify `i', we suggest to translate the
     declaration to an initialized variable. The EP syntax is:

          var
            i : Integer value 0;

     GPC supports this as well as the following mixtureof dialects:

          var
            i : Integer = 0;

     Furthermore, you can also assign initialization values to types:

          program InitTypeDemo;
          
          type
            MyInteger = Integer value 42;
          
          var
            i : MyInteger;
          
          begin
            WriteLn (i)
          end.

     Here, all variables of type MyInteger are automatically initialized
     to 0 when created.

   * Arrays initializers look like this in BP:

          program BPArrayInitDemo;
          
          const
            MyStringsCount = 5;
          
          type
            Ident = String [20];
          
          const
            MyStrings : array [1 .. MyStringsCount] of Ident =
              ('export', 'implementation', 'import',
               'interface', 'module');
          
          begin
          end.

     And the following way in EP:

          program EPArrayInitDemo;
          
          {$W no-field-name-problem} { avoid a warning by GPC }
          
          const
            MyStringsCount = 5;
          
          type
            Ident = String (20);
          
          var
            MyStrings : array [1 .. MyStringsCount] of Ident value
              [1 : 'export'; 2 : 'implementation'; 3 : 'import';
               4 : 'interface'; 5 : 'module'];
          
          begin
          end.

     There seem to be pros and cons to each style. GPC supports both as
     well as just about any thinkable mixture of them.

     Some folks don't like having to specify an index since it requires
     renumbering if you want to add a new item to the middle. However,
     if you index by an enumerated type, you might be able to avoid
     major renumbering by hand.


   *See also* *Note Subroutine Parameter List Declaration::


File: gpc,  Node: Type Declaration,  Next: Variable Declaration,  Prev: Constant Declaration,  Up: Source Structures

7.1.4 Type Declaration
----------------------

   A type declaration looks like this:

     type
       TYPE IDENTIFIER = TYPE DEFINITION;
       ...
       TYPE IDENTIFIER = TYPE DEFINITION;
   or, with preset content:
     type
       TYPE IDENTIFIER = TYPE DEFINITION value CONSTANT EXPRESSION;
       ...
       TYPE IDENTIFIER = TYPE DEFINITION value CONSTANT EXPRESSION;

   A type declaration part begins with the reserved word `type'.  It
declares a TYPE IDENTIFIER which is defined by TYPE DEFINITION.  A type
definition either can be an array, a record, a schema, a set, an
object, a subrange, an enumerated type, a pointer to another type
identifier or simply another type identifier which is to alias.  If a
schema type is to be declared, TYPE IDENTIFIER is followed by a
discriminant enclosed in parentheses:

     TYPE IDENTIFIER (DISCRIMINANT) = SCHEMA TYPE DEFINITION;

   If `value' is specified, followed by a constant satisfying the type
definition, every variable of this type is initialized with CONSTANT
EXPRESSION, unless it is initialized by `value' itself.  The reserved
word `value' can be replaced by `=', however `value' is not allowed in
ISO-Pascal and Borland Pascal, and the replacement by `=' is not
allowed in Extended Pascal.


   Type declaration example:

     type
       { This side is the }     { That side is the }
       { type declaration }     { type definition  }
     
       arrayfoo            = array [0..9] of Integer;  { array definition }
       recordfoo           = record                    { record definition }
                               bar : Integer;
                             end;
     
            { schema def with discriminant ``x,y : Integer'' }
       schemafoo (x,y : Integer) = array [x..y] of Integer;
       charsetfoo          = set of Char;              { Def of a set }
       objectfoo           = object                    { Def of an object }
                               procedure DoAction;
                               constructor Init;
                               destructor Done;
                             end;
       subrangefoo         = -123..456;                { subrange def }
     
       enumeratedfoo       = (Pope,John,the,Second);   { enum type def }
            { Def of a pointer to another type identifier }
       pinteger            = ^arrayfoo;
            { Def of an alias name for another type identifier }
       identityfoo         = Integer;
            { Def of an integer which was initialized by 123 }
       initializedfoo      = Integer value 123;


   *See also*  *Note Type Definition::, *Note Data Types::, *Note
Variable Declaration::


File: gpc,  Node: Variable Declaration,  Next: Subroutine Declaration,  Prev: Type Declaration,  Up: Source Structures

7.1.5 Variable Declaration
--------------------------

   A variable declaration looks like this:

     var
       VARIABLE IDENTIFIER: TYPE IDENTIFIER;
       ...
       VARIABLE IDENTIFIER: TYPE IDENTIFIER;
   or
     var
       VARIABLE IDENTIFIER: TYPE DEFINITION;
       ...
       VARIABLE IDENTIFIER: TYPE DEFINITION;
   and with initializing value:
     var
       VARIABLE IDENTIFIER: TYPE IDENTIFIER value CONSTANT EXPRESSION;
       ...
       VARIABLE IDENTIFIER: TYPE IDENTIFIER value CONSTANT EXPRESSION;
   or
     var
       VARIABLE IDENTIFIER: TYPE DEFINITION value CONSTANT EXPRESSION;
       ...
       VARIABLE IDENTIFIER: TYPE DEFINITION value CONSTANT EXPRESSION;

   A variable declaration part begins with the reserved word `var'.  It
declares a VARIABLE IDENTIFIER whose type either can be specified by a
type identifier, or by a type definion which either can be an array, a
record, a set, a subrange, an enumerated type or a pointer to an type
identifier.  If `value' is specified followed by a constant expression
satisfying the specified type, the variable declared is initialized with
CONSTANT EXPRESSION.  The reserved word `value' can be replaced by `=',
however `value' is not allowed in ISO-Pascal and Borland Pascal, and the
replacement by `=' is not allowed in Extended Pascal.


   *See also* *Note Type Definition::, *Note Type Declaration::, *Note
Data Types::, *Note The Declaring Statement::, *Note Subroutine
Parameter List Declaration::


File: gpc,  Node: Subroutine Declaration,  Next: Statements,  Prev: Variable Declaration,  Up: Source Structures

7.1.6 Subroutine Declaration
----------------------------

* Menu:

* The Procedure::
* The Function::
* The Operator::
* Subroutine Parameter List Declaration::


File: gpc,  Node: The Procedure,  Next: The Function,  Up: Subroutine Declaration

7.1.6.1 The Procedure
.....................

     procedure PROCEDURE IDENTIFIER;
     DECLARATION PART
     begin
       STATEMENT PART
     end;
   or with a parameter list:
     procedure PROCEDURE IDENTIFIER (PARAMETER LIST);
     DECLARATION PART
     begin
       STATEMENT PART
     end;

   A procedure is quite like a sub-program: The DECLARATION PART
consists of label, constant, type, variable or subroutine declarations
in free order. The STATEMENT PART consists of a sequence of statements.
If PARAMETER LIST is specified, parameters can be passed to the
procedure and can be used in STATEMENT PART. A recursive procedure call
is allowed.


   *See also* *Note The Function::, *Note Subroutine Parameter List
Declaration::


File: gpc,  Node: The Function,  Next: The Operator,  Prev: The Procedure,  Up: Subroutine Declaration

7.1.6.2 The Function
....................

     function FUNCTION IDENTIFIER: FUNCTION RESULT TYPE;
     DECLARATION PART
     begin
       STATEMENT PART
     end;
   or with a parameter list:
     function FUNCTION IDENTIFIER (PARAMETER LIST): FUNCION RESULT TYPE;
     DECLARATION PART
     begin
       STATEMENT PART
     end;

   A function is a subroutine which has a return value of type FUNCTION
RESULT TYPE. It is structured like the program: the DECLARATION PART
consists of label, constant, type, variable or subroutine declarations
in free order. The STATEMENT PART consists of a sequence of statements.
If PARAMETER LIST is specified, parameters can be passed to the
function and can be used in STATEMENT PART. The return value is set via
an assignment:
     FUNCTION IDENTIFIER := EXPRESSION
   Recursive function calls are allowed. Concerning the result type,
ISO-7185 Pascal and Borland Pascal only allow the intrinsic types,
subranges, enumerated types and pointer types to be returned. In
Extended Pascal, FUNCTION RESULT TYPE can be every assignable type.  Of
course, there are no type restrictions in GNU Pascal as well.  If
extended syntax is switched on, functions can be called like procedures
via procedure call statement.


   *See also* *Note The Procedure::, *Note Subroutine Parameter List
Declaration::, *Note Data Types::


File: gpc,  Node: The Operator,  Next: Subroutine Parameter List Declaration,  Prev: The Function,  Up: Subroutine Declaration

7.1.6.3 The Operator
....................

   GNU Pascal allows to define operators which can be used the infix
style in expressions. For a more detailed description, see *Note
Operators::


File: gpc,  Node: Subroutine Parameter List Declaration,  Prev: The Operator,  Up: Subroutine Declaration

7.1.6.4 Subroutine Parameter List Declaration
.............................................

     PARAMETER; ...; PARAMETER

   Value parameters are declared this way:
     PARAMETER IDENTIFIER: PARAMETER TYPE
   where parameters of the same type be listed, separated by commata:
     PARAMETER IDENTIFIER, ..., PARAMETER IDENTIFIER: PARAMETER TYPE

   If `var' is specified before a parameter, which is an USCD extension,
the compiler is told to pass the argument by reference, i.e. the
parameter passed to is expected to be an L-value whose type is
PARAMETER TYPE if specified, else it is compatible with any type:
     var PARAMETER IDENTIFIER: PARAMETER TYPE
   or without type specification:
     var PARAMETER IDENTIFIER
   This declaration is necessary if the parameter is to be modified
within a block and to hold its value still after return. Otherwise, the
parameter remains unchanged after block exit, since it is passed by
value, and therefore it is called value parameter.

   A parameter of this kind is called variable parameter and
corresponds to an L-value pointer (to TYPE IDENTIFIER if specified).
As a Borland Pascal extension, there are also constant parameters which
are not allowed to be changed in the related statement part.  Like
variable parameters, the type needs not to be declared; in this case
PARAMETER IDENTIFIER is treated as a typeless parameter.
     const PARAMETER IDENTIFIER: PARAMETER TYPE
   or without any further type specification:
     const PARAMETER IDENTIFIER

   As an Extended Pascal extension, there is a way to declare procedural
parameters directly:
     procedure PARAMETER IDENTIFIER
   or without type specification:
     function PARAMETER IDENTIFIER: PARAMETER IDENTIFIER RESULT TYPE

   Example for parameter lists:
     procedure Foo (var Bar; var Baz: Integer; const Fred: Integer);
     
       procedure Glork1 (function Foo: Integer; procedure Bar (Baz: Integer));
       begin
         Bar (Foo)
       end;
     
     begin
       baz := Integer (Bar) + Fred
     end;


   *See also* *Note Data Types::


File: gpc,  Node: Statements,  Next: Modules and Units,  Prev: Subroutine Declaration,  Up: Source Structures

7.1.7 Statements
----------------

* Menu:

* Assignment::
* begin end Compound Statement::
* if Statement::
* case Statement::
* for Statement::
* while Statement::
* repeat Statement::
* asm Inline::
* with Statement::
* goto Statement::
* Procedure Call::
* The Declaring Statement::
* Loop Control Statements::


File: gpc,  Node: Assignment,  Next: begin end Compound Statement,  Up: Statements

7.1.7.1 Assignment
..................

   The way an assignment looks like:
     L-VALUE := EXPRESSION;

   This statement assigns any valid expression to L-VALUE. Make sure
that the result of EXPRESSION is compatible with L-VALUE, otherwise an
compilation error is reported. The `:=' is called assignment operator.
As long as L-VALUE and EXPRESSION are type compatible, they are
assignment compatible for _any definable type_ as well.


File: gpc,  Node: begin end Compound Statement,  Next: if Statement,  Prev: Assignment,  Up: Statements

7.1.7.2 begin end Compound Statement
....................................

   It looks like that:
     begin
       STATEMENT;
       STATEMENT;
       ...
       STATEMENT
     end

   This statement joins several STATEMENTS together into one compound
statement which is treated as a single statement by the compiler. The
finishing semicolon before `end' can be left out.


File: gpc,  Node: if Statement,  Next: case Statement,  Prev: begin end Compound Statement,  Up: Statements

7.1.7.3 if Statement
....................

   This statement has the following look:
     if BOOLEAN EXPRESSION then
       STATEMENT
   or with an alternative statement:
     if BOOLEAN EXPRESSION then
       STATEMENT1
     else
       STATEMENT2

   The `if' ... `then' statement consists of a boolean expression and a
STATEMENT, which is conditionally executed if the evaluation of BOOLEAN
EXPRESSION yields true.

   If `if' ... `then' ... `else' is concerned, STATEMENT1 is executed
depending on BOOLEAN EXPRESSION being true, otherwise STATEMENT2 is
executed alternatively. Note: the statement before else _must not_
finish with a semicolon.


File: gpc,  Node: case Statement,  Next: for Statement,  Prev: if Statement,  Up: Statements

7.1.7.4 case Statement
......................

     case EXPRESSION of
       SELECTOR: STATEMENT;
       ...
       SELECTOR: STATEMENT;
     end
   or, with alternative statement sequence:
     case ORDINAL EXPRESSION of
       SELECTOR: STATEMENT;
       ...
       SELECTOR: STATEMENT;
     otherwise                   { ``else'' instead of ``otherwise'' allowed }
       STATEMENT;
       ...
       STATEMENT;
     end
   or, as part of the invariant `record' type definition:
     type
       foo = record
         FIELD DECLARATIONS
       case bar: VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
       end;
   or, without a variant selector field,
     type
       foo = record
         FIELD DECLARATIONS
       case VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
       end;

   The `case' statement compares the value of ORDINAL EXPRESSION to
each SELECTOR, which can be a constant, a subrange, or a list of them
separated by commata, being compatible with the result of ORDINAL
EXPRESSION.  Note: duplicate selectors or range crossing is not allowed
unless {$borland-pascal} is specified. In case of equality the
corresponding statement is executed. If `otherwise' is specified and no
appropriate selector matched the expression, the series of statements
following `otherwise' is executed. As a synonym for `otherwise', `else'
can be used. The semicolon before `otherwise' is optional.


   @@ ????  The expression _must_ match one of the selectors in order
to continue, unless an alternative statement series is specified.

   For `case' in a variant record type definition, see *Note Record
Types::.


   *See also* *Note if Statement::


File: gpc,  Node: for Statement,  Next: while Statement,  Prev: case Statement,  Up: Statements

7.1.7.5 for Statement
.....................

   For ordinal index variables:
     for ORDINAL VARIABLE := INITIAL VALUE to FINAL VALUE do
       STATEMENT
   or
     for ORDINAL VARIABLE := INITIAL VALUE downto FINAL VALUE do
       STATEMENT

   For sets:
     for SET ELEMENT TYPE VARIABLE in SOME SET do
       STATEMENT

   For pointer index variables:
     for POINTER VARIABLE := INITIAL ADDRESS to FINAL ADDRESS do
       STATEMENT
   or
     for POINTER VARIABLE := INITIAL ADDRESS downto FINAL ADDRESS do
       STATEMENT

   The FOR statement is a control statement where an index variable
assumes every value of a certain range and for every value the index
variable assumes STATEMENT is executed. The range can be specified by
two bounds (which must be of the same type as the index variable, i.e.
ordinal or pointers) or by a set.


   For ordinal index variables: If `to' is specified, the index counter
is increased by one as long as INITIAL VALUE is less or equal to FINAL
VALUE, if `downto' is specified, it is decreased by one as long as
INITIAL VALUE is greater or equal to FINAL VALUE.


   For pointer index variables: If `to' is specified, the index counter
is increased by the size of the type the index variable points to (if
it is a typed pointer, otherwise by one if it is typeless) as long as
INITIAL ADDRESS is less or equal to FINAL ADDRESS, if `downto' is
specified, it is decreased by a corresponding value as long as INITIAL
ADDRESS is greater or equal to FINAL ADDRESS. Since gpc provides a flat
memory modell, all addresses are linear, so they can be compared.


   For sets: STATEMENT is executed with the index variable (which must
be ordinal and of the same type as the set elements) assuming every
element in SOME SET, however note that a set is a not-ordered structure.


   Note: A modification of the index variable may result in
unpredictable action.


   *See also* *Note Set Types::, *Note Pointer Arithmetics::, *Note
repeat Statement::, *Note for Statement::


File: gpc,  Node: while Statement,  Next: repeat Statement,  Prev: for Statement,  Up: Statements

7.1.7.6 while Statement
.......................

   The while loop has the following form
     while BOOLEAN EXPRESSION do
       STATEMENT

   The `while' statement declares a loop which is executed while
BOOLEAN EXPRESSION is true. Since the terminating condition is checked
before execution of the loop body, STATEMENT may never be executed.


   *See also* *Note repeat Statement::, *Note for Statement::


File: gpc,  Node: repeat Statement,  Next: asm Inline,  Prev: while Statement,  Up: Statements

7.1.7.7 repeat Statement
........................

     repeat
       STATEMENT;
       ...
       STATEMENT;
     until BOOLEAN EXPRESSION

   The `repeat' ... `until' statement declares a loop which is repeated
until BOOLEAN EXPRESSION is true. Since the terminating condition is
checked after execution of the loop body, the statement sequence is
executed at least once.


   *See also* *Note while Statement::, *Note for Statement::


File: gpc,  Node: asm Inline,  Next: with Statement,  Prev: repeat Statement,  Up: Statements

7.1.7.8 asm Inline
..................

   @@ ????
     asm (StatementList : String);

   The `asm' inline statement is a GNU extension. It requires its
paramenter to be AT&T-noted assembler statements, and therefore it is
not compatible with that one of Borland Pascal. STATEMENTLIST is a
string containing asm statements seperated by semicola.


File: gpc,  Node: with Statement,  Next: goto Statement,  Prev: asm Inline,  Up: Statements

7.1.7.9 with Statement
......................


File: gpc,  Node: goto Statement,  Next: Procedure Call,  Prev: with Statement,  Up: Statements

7.1.7.10 goto Statement
.......................

   @@ ????  This statement looks like this:
     goto LABEL

   (Under construction.)


File: gpc,  Node: Procedure Call,  Next: The Declaring Statement,  Prev: goto Statement,  Up: Statements

7.1.7.11 Procedure Call
.......................

     SUBROUTINE NAME;

   This statement calls the subroutine SUBROUTINE NAME which can either
be a procedure or, if GNU extended syntax is turned on, a function. In
this case, the return value is ignored.


File: gpc,  Node: The Declaring Statement,  Next: Loop Control Statements,  Prev: Procedure Call,  Up: Statements

7.1.7.12 The Declaring Statement
................................

   This statement allows to declare a variable within a statement part.
It looks like this:
     var
       VARIABLE IDENTIFIER: TYPE IDENTIFIER;
   or
     var
       VARIABLE IDENTIFIER: TYPE DEFINITION;
   and with initializing value:
     var
       VARIABLE IDENTIFIER: TYPE IDENTIFIER value EXPRESSION;
   or
     var
       VARIABLE IDENTIFIER: TYPE DEFINITION value EXPRESSION;

   Unlike in declaration parts, the initializing EXPRESSION has not to
be a constant expression. Note that every declaring statement has to
start with `var'. The name space of VARIABLE IDENTIFIER extends from
its declaration to the end of the current matching statement sequence
(which can be a statement part (of the program, a function, a procedure
or an operator) or, within that part, a begin end compound statement, a
repeat loop, or the else branch of a case statement). This statement is
a GNU extension.


   *See also* *Note Type Definition::, *Note Data Types::


File: gpc,  Node: Loop Control Statements,  Prev: The Declaring Statement,  Up: Statements

7.1.7.13 Loop Control Statements
................................

   These are
     Continue;
   and
     Break;

   These simple statements _must not_ occur outside a loop, i.e. a for,
while or repeat statement. `Continue' transfers control to the beginning
of the loop right by its call, `Break' exits the current loop turn and
continues loop execution.


File: gpc,  Node: Modules and Units,  Prev: Statements,  Up: Source Structures

7.1.8 Import Part and Module/Unit Concept
-----------------------------------------

* Menu:

* Modules::   The source structure of ISO-10206 Extended Pascal Modules.
* Units::     The source structure of UCSD/Borland Pascal Units.


File: gpc,  Node: Modules,  Next: Units,  Up: Modules and Units

7.1.8.1 The Source Structure of ISO-10206 Extended Pascal Modules
.................................................................

   @@ Description missing here

   A module can have one or more `export' clauses and the name of an
`export' clause doesn't have to be equal to the name of the module.

   Sample module code with separate `interface' and `implementation'
parts:

     module DemoModule interface;  { interface part }
     
     export DemoModule = (FooType, SetFoo, GetFoo);
     
     type
       FooType = Integer;
     
     procedure SetFoo (f : FooType);
     function  GetFoo : FooType;
     
     end.
     
     module DemoModule implementation;  { implementation part }
     
     import
       StandardInput;
       StandardOutput;
     
     var
       Foo : FooType;
     
     { Note: the effect is the same as a `forward' directive would have:
       parameter lists and return types are not allowed in the
       declaration of exported routines, according to EP. In GPC, they
       are allowed, but not required. }
     procedure SetFoo;
     begin
       Foo := f
     end;
     
     function GetFoo;
     begin
       GetFoo := Foo
     end;
     
     to begin do
       begin
         foo := 59;
         WriteLn ('Just an example of a module initializer. See comment below')
       end;
     
     to end do
       begin
         Foo := 0;
         WriteLn ('Goodbye')
       end;
     
     end.

   Alternatively the module interface and implementation may be
combined as follows:

     module DemoMod2; { Alternative method }
     
     export Catch22 = (FooType, SetFoo, GetFoo);
     
     type
       FooType = Integer;
     
     procedure SetFoo (f : FooType);
     function  GetFoo : FooType;
     
     end; { note: this end is required here, even if the
            module-block below would be empty. }
     
     var
       Foo : FooType;
     
     procedure SetFoo;
     begin
       Foo := f
     end;
     
     function GetFoo;
     begin
       GetFoo := Foo
     end;
     
     end.

   Either one of the two methods may be used like this:

     program ModuleDemo (Output);
     
     import DemoModule;
     
     begin
       SetFoo (999);
       WriteLn (GetFoo);
     end.

     program ModDemo2 (Output);
     
     import Catch22 in 'demomod2.pas';
     
     begin
       SetFoo (999);
       WriteLn (GetFoo);
     end.

   Somewhat simpler GPC modules are also supported. *Note:* This is not
supported in the Extended Pascal standard.

   This is a simpler module support that does not require exports,
imports, module headers etc.

   These non-standard simple GPC modules look like (does not have an
export part, does not have a separate module-block, does not use
import/export features.)

     module DemoMod3;
     
     type
       FooType = Integer;
     
     var
       Foo : FooType;
     
     procedure SetFoo (f : FooType);
     begin
       Foo := f
     end;
     
     function GetFoo : FooType;
     begin
       GetFoo := Foo;
     end;
     
     end.
     
     program ModDemo3 (Output);
     
     { Manually do the "import" from DemoMod3 }
     type
       FooType = Integer;
     
     procedure SetFoo (f : FooType); external;
     function  GetFoo : FooType;     external;
     
     begin
       SetFoo (999);
       WriteLn (GetFoo)
     end.

   Module initialization and finalization:

   The `to begin do' module initialization and `to end do' module
finalization constructs now work on _every_ target.

   By the way: The "GPC specific" module definition is almost identical
to the PXSC standard. With an additional keyword `global' which puts a
declaration into an export interface with the name of the module, it
will be the same. @@This is planned.


File: gpc,  Node: Units,  Prev: Modules,  Up: Modules and Units

7.1.8.2 The Source Structure of UCSD/Borland Pascal Units
.........................................................

   A generic GNU Pascal unit looks like the following:

     unit NAME;
     
     interface
     
     IMPORT PART
     
     INTERFACE PART
     
     implementation
     
     IMPLEMENTATION PART
     
     INITIALIZATION PART
     
     end.

   The NAME of the unit should coincide with the name of the file with
the extension stripped. (If not, you can tell GPC the file name with
`uses foo in 'bar.pas'', see *Note uses::.)

   The IMPORT PART is either empty or contains a `uses' clause to
import other units. It may also consist of an ISO-style `import'
specification. Note that the implementation part is not preceeded by a
second import part in GPC (see *Note import::).

   The INTERFACE PART consists of constant, type, and variable
declarations, procedure and function headings which may be freely mixed.

   The IMPLEMENTATION PART is like the declaration part of a program,
but the headers of procedures and functions may be abbreviated:
Parameter lists and function return values may be omitted for
procedures and functions already declared in the interface part.

   The INITIALIZATION PART may be missing, or it may be a `begin'
followed by one or more statements, such that the unit has a statement
part between this `begin' and the final `end'. Alternatively, a unit
may have ISO-style module initializers and finalizers, see *Note to
begin do::, *Note to end do::.

   Note that GPC does _not_ yet check whether all interface
declarations are resolved in the same unit. Procedures and functions
which are in fact not used may be omitted, and/or procedures and
functions may be implemented somewhere else, even in a different
language. However, relying on a GPC bug (that will eventually be fixed)
is not a good idea, so this is not recommended.

   A unit exports everything declared in the interface section. The
exported interface has the name of the unit and is compatible with
Extended Pascal module interfaces since GPC uses the same code to
handle both.


File: gpc,  Node: Data Types,  Next: Operators,  Prev: Source Structures,  Up: Programming

7.2 Data Types
==============

* Menu:

* Type Definition::                         The Declaration Part
* Ordinal Types::                           Built-in Ordinal Types
* Integer Types::                           Built-in Integer Types
* Real Types::                              Built-in Real Types
* String Types::                            Built-in Character and String Types
* Character Types::                         Built-in Chararacter Types. See Ordinal Types
* File Types::                              Built-in Types for File Handling
* Boolean (Intrinsic)::                     Built-in Type for Boolean values.
* Pointer (Intrinsic)::                     The Intrinsic Pointer Type
* Type Definition Possibilities::           User-defined Types
* Machine-dependent Type Implementation::   Differences in Implementation


File: gpc,  Node: Type Definition,  Next: Ordinal Types,  Up: Data Types

7.2.1 Type Definition
---------------------

   As described in *Note Type Declaration::, a type declaration part
looks like this:
     type
        TYPE IDENTIFIER = TYPE DEFINITION;
        ...
        TYPE IDENTIFIER = TYPE DEFINITION;
   where the left side is the type declaration and the right one the
type definition side. GNU Pascal offers variant possibilities to
implement highly specialized and problem-specific data types.


File: gpc,  Node: Ordinal Types,  Next: Integer Types,  Prev: Type Definition,  Up: Data Types

7.2.2 Ordinal Types
-------------------

   An ordinal type is a range of whole numbers. It includes integer
types, character types and subrange types of them.

   A character type is represented by the intrinsic type `Char' which
can hold elements of the operating system's character set (usually
ASCII).  Conversion between character types and ordinal types is
possible with the intrinsic functions `Ord' and `Chr' or type casting
techniques.

     type
       Foo: Char;       { foo can hold a character }
       Num: '0' .. '9'; { Can hold decimal ciphers, is a subrange type of Char }

   *See also* *Note Ord::, *Note Chr::, *Note Type Casts::


File: gpc,  Node: Integer Types,  Next: Real Types,  Prev: Ordinal Types,  Up: Data Types

7.2.3 Integer Types
-------------------

   Besides `Integer', GNU Pascal supports a large zoo of integer types.
Some of them you will find in other compilers, too, but most are GNU
extensions, introduced for particular needs. Many of these types are
synonyms for each other. In total, GPC provides 20 built-in integer
types, plus seven families you can play with. (Four of these "families"
are signed and unsigned, packed and unpacked subrange types; the others
are explained below.)

* Menu:

* Natural Integer Types::
* Main Branch Integer Types::
* Integer Types with Specified Size::
* Integer Types and Compatibility::
* Summary of Integer Types::

   See also: *Note Subrange Types::.


File: gpc,  Node: Natural Integer Types,  Next: Main Branch Integer Types,  Up: Integer Types

7.2.3.1 The CPU's Natural Integer Types
.......................................

   For most purposes, you will always use `Integer', a signed integer
type which has the "natural" size of such types for the machine. On
most machines GPC runs on, this is a size of 32 bits, so `Integer'
usually has a range of `-2147483648..2147483647' (see *Note Integer::).

   If you need an unsigned integer type, the "natural" choice is
`Cardinal', also called `Word'. Like `Integer', it has 32 bits on most
machines and thus a range of `0..4294967295' (see *Note Cardinal::,
*Note Word::).

   These natural integer types should be your first choice for best
performance. For instance on an Intel x86 CPU operations with `Integer'
usually work faster than operations with shorter integer types like
`ShortInt' or `ByteInt' (see below).


File: gpc,  Node: Main Branch Integer Types,  Next: Integer Types with Specified Size,  Prev: Natural Integer Types,  Up: Integer Types

7.2.3.2 The Main Branch of Integer Types
........................................

   `Integer', `Cardinal', and `Word' define the three "main branches"
of GPC's integer types. You won't always be able to deal with the
natural size; sometimes something smaller or longer will be needed.
Especially when interfacing with libraries written in other languages
such as C, you will need equivalents for their integer types.

   The following variants of `Integer', `Cardinal' and `Word' are
guaranteed to be compatible to the integer types of GNU C. The sizes
given, however, are _not_ guaranteed. They are just typical values
currently used on most platforms, but they may be actually shorter or
increase in the future.

signed      unsigned     also unsigned    GNU C equivalent            size in bits
                                                                      (typically)
ByteInt     ByteCard     Byte             [un]signed char              8
ShortInt    ShortCard    ShortWord        [unsigned] short int        16
Integer     Cardinal     Word             [unsigned] int              32
MedInt      MedCard      MedWord          [unsinged] long int         32
LongInt     LongCard     LongWord         [unsinged] long long int    64

   Since we don't know whether `LongInt' will always remain the
"longest" integer type available - maybe GNU C will get `long long long
int', one day, which we will support as `LongLongInt' - we have added
the synonym `LongestInt' for the longest available singed integer type,
and the same holds for `LongestCard' and `LongestWord'.


File: gpc,  Node: Integer Types with Specified Size,  Next: Integer Types and Compatibility,  Prev: Main Branch Integer Types,  Up: Integer Types

7.2.3.3 Integer Types with Specified Size
.........................................

   In some situations you will need an integer type of a well-defined
size. For this purpose, GNU Pascal provides three families of signed
and unsinged integer types. The type

     Integer (42)

is guaranteed to have a precision of 42 bits. In a realistic context,
you will most often give a power of two as the number of bits, and the
machine you will need it on will support variables of that size. If
this is the case, the specified precision will simultaneously be the
amount of storage needed for variables of this type.

   In short: If you want to be sure that you have a signed integer with
32 bits width, write `Integer (32)', not just `Integer' which might be
bigger. The same works with `Cardinal' and `Word' if you need unsigned
integer types of well-known size.

   This way, you _can't_ get a higher precision than that of
`LongestInt' or `LongestCard' (see *Note Main Branch Integer Types::).
If you need higher precision, you can look at the `GMP' unit (*note
GMP::) which provides integer types with arbitrary precision, but their
usage is different from normal integer types.


File: gpc,  Node: Integer Types and Compatibility,  Next: Summary of Integer Types,  Prev: Integer Types with Specified Size,  Up: Integer Types

7.2.3.4 Integer Types and Compatibility
.......................................

   If you care about ISO compliance, _only_ use `Integer' and subranges
of `Integer'.

   Some of GPC's non-ISO integer types exist in Borland Pascal, too:
`Byte', `ShortInt', `Word', and `LongInt'. The sizes of these types,
however, are not the same as in Borland Pascal. Even for `Byte' this is
not guaranteed (while probable, though).

   When designing GNU Pascal, we thought about compatibility to Borland
Pascal. Since GNU Pascal is (at least) a 32-bit compiler, `Integer'
_must_ have (at least) 32 bits. But what to do with `Word'? Same size
as `Integer' (like in BP) or 16 bits (like in BP)? We decided to make
`Word' the "natural-sized" unsigned integer type, thus making it (at
least) 32 bits wide. Similarly, we decided to give `LongInt' twice the
size of `Integer' (like in BP) rather than making it 32 bits wide (like
in BP). So `LongInt' has 64 bits, and `ShortInt' has 16 bits on the
Intel x86 platforms.

   On the other hand, to increase compatibility to Borland Pascal and
Delphi, GPC provides the alias name `Comp' for `LongInt' (64 bits on
Intel x86) and `SmallInt' for `ShortInt' (16 bits on Intel x86). Note
that BP treats `Comp' as a "real" type and allows assignments like
`MyCompVar := 42.0'. Since we don't consider this a feature, GPC does
not copy this behaviour.


File: gpc,  Node: Summary of Integer Types,  Prev: Integer Types and Compatibility,  Up: Integer Types

7.2.3.5 Summary of Integer Types
................................

   Here is a summary of all integer types defined in GPC. The sizes and
ranges are only _typical_ values, valid on some, but not all platforms.
Compatibility to GNU C however _is_ guaranteed.

*Note ByteInt::
     signed 8-bit integer type, `-128..128',
     compatible to `signed char' in GNU C.

*Note Byte: ByteCard
     unsigned 8-bit integer type, `0..255',
     compatible to `unsigned char' in GNU C.

*Note ShortInt::
     signed 16-bit integer type, `-32768..32767',
     compatible to `short int' in GNU C.

*Note ShortWord: ShortCard
     unsigned 16-bit integer type, `0..65535',
     compatible to `unsigned short int' in GNU C.

*Note Integer::
     signed 32-bit integer type, `-2147483648..2147483647',
     compatible to `int' in GNU C.

*Note Word: Cardinal
     unsigned 32-bit integer type, `0..4294967295',
     compatible to `unsigned int' in GNU C.

*Note MedInt::
     signed 32-bit integer type, `-2147483648..2147483647',
     compatible to `long int' in GNU C.

*Note MedWord: MedCard
     unsigned 32-bit integer type, `0..4294967295',
     compatible to `unsigned long int' in GNU C.

*Note LongInt::
     signed 64-bit integer type,
     `-9223372036854775808..9223372036854775807',
     compatible to `long long int' in GNU C.

*Note LongWord: LongCard
     unsigned 64-bit integer type, `0..18446744073709551615',
     compatible to `unsigned long long int' in GNU C.

*Note LongestInt::
     signed 64-bit integer type,
     `-9223372036854775808..9223372036854775807'.

*Note LongestWord: LongestCard
     unsigned 64-bit integer type, `0..18446744073709551615'.

*Note Comp::
     signed 64-bit integer type,
     `-9223372036854775808..9223372036854775807'.

*Note SmallInt::
     signed 16-bit integer type, `-32768..32767'.

   To specify the number of bits, use

`Integer (N)'
     signed N-bit integer type.

`Cardinal (N)'
     unsigned N-bit integer type.

`Word (N)'
     unsigned N-bit integer type.

     program IntegerTypesDemo (Output);
     
     var
       ByteVar : Byte;
       ShortIntVar : ShortInt;
       Foo : MedCard;
       Big : LongestInt;
     
     begin
       ShortIntVar := 1000;
       Big := MaxInt * ShortIntVar;
       ByteVar := 127;
       Foo := 16#deadbeef
     end.

   See also: *Note Subrange Types::.


File: gpc,  Node: Real Types,  Next: String Types,  Prev: Integer Types,  Up: Data Types

7.2.4 Built-in Real (Floating Point) Types
------------------------------------------

   GPC has three built-in floating point types to represent real
numbers. Each of them is available under two names (for compatibility
to other compilers and languages).

   For most purposes, you will always use `Real' which is the only one
of them that is part of Standard and Extended Pascal. If memory
constraints apply, you might want to choose `ShortReal' for larger
arrays. On the other hand, if high precision is needed, you can use
`LongReal'. When interfacing with libraries written in other languages
such as C, you will need the equivalents for their real types.

   Note that not all machines support longer floating point types, so
`LongReal' is the same as `Real' on these machines. Also, some machines
may support a longer type, but not do all arithmetic operations (e.g.
the `Sin' function, *Note Sin::) in a precision higher than that of
`Real'. If you need higher precision, you can look at the `GMP' unit
(*note GMP::) which provides rational and real numbers with arbitrary
precision, but their usage is different from normal real types.

   The following real types are guaranteed to be compatible to the real
types of GNU C. The sizes given, however, are _not_ guaranteed.  They
are just typical values used on any IEEE compatible floating point
hardware, but they may be different on some machines.

type name    alternative name    GNU C equivalent    size in bits (typically)
ShortReal    Single              float               32
Real         Double              double              64
LongReal     Extended            long double         80


File: gpc,  Node: String Types,  Next: Character Types,  Prev: Real Types,  Up: Data Types

7.2.5 Strings Types
-------------------

   There are several ways to use strings in GNU Pascal. One of them is
the use of the intrinsic string type `String' which is a predefined
schema type. The schema discriminant of this type holds the maximal
length, which is of type Integer, so values up to `MaxInt' can be
specified. For `String', an assignment is defined. There are many
built-in functions and procedures for comfortable strings handling.

   @@ ???? String procedures and functions.

   Another way to use strings is to use arrays of type `Char'. For
these, an intrinsic assignment is defined as well. Besides, `String'
and `Char' are assignment compatible. The preferred way, however, is
`String' because of the numerous possibilities for string handling.


File: gpc,  Node: Character Types,  Next: File Types,  Prev: String Types,  Up: Data Types

7.2.6 Character Types
---------------------

   Character types are a special case of ordinal types. See *Note
Ordinal Types::


File: gpc,  Node: File Types,  Next: Boolean (Intrinsic),  Prev: Character Types,  Up: Data Types

7.2.7 File Types
----------------

   @@ ???? I think that's something for someone who might know what he
is doing


File: gpc,  Node: Boolean (Intrinsic),  Next: Pointer (Intrinsic),  Prev: File Types,  Up: Data Types

7.2.8 Boolean (Intrinsic)
-------------------------

   The intrinsic Boolean represents boolean values, i.e. it can only
assume true and false (which are predefined constants). This type
corresponds to the enumerated type
     type
       Boolean = (False, True);
   Since it is declared this way, it follows:
     Ord (False) = 0
     Ord (True) = 1
     False < True
    There are four intrinsic logical operators. The logical `and',
`or' and `not'. In Borland Pascal and GNU Pascal, there is  a logical
"exclusive or" `xor'.


   *See also* *Note Enumerated Types::, *Note and::, *Note or::, *Note
not::, *Note xor::


File: gpc,  Node: Pointer (Intrinsic),  Next: Type Definition Possibilities,  Prev: Boolean (Intrinsic),  Up: Data Types

7.2.9 Pointer (Intrinsic)
-------------------------

   The intrinsic Pointer Type is a so-called unspecified or typeless
pointer (i.e. a pointer which does not point to any type but holds
simply a memory address).


   *See also* *Note Pointer Types::, *Note nil::


File: gpc,  Node: Type Definition Possibilities,  Next: Machine-dependent Type Implementation,  Prev: Pointer (Intrinsic),  Up: Data Types

7.2.10 Type Definition Possibilities
------------------------------------

* Menu:

* Subrange Types::     Packed and non-packed Subranges
* Enumerated Types::   Enumerated Types
* Array Types::        Fields (Array Types)
* Record Types::       Structured Types (Record Types)
* Variant Records::    Record Types with Variing Fields
* Schema Types::       Schema Types
* Set Types::          Set Types
* Pointer Types::      Pointer Types
* Procedural Types::   Procedures Types
* Object Types::       Types for Object-Oriented Programming
* Type Initializers::  Types Carrying an Initial Value for Variables
* Restricted Types::   Hiding Internal Information about Types


File: gpc,  Node: Subrange Types,  Next: Enumerated Types,  Up: Type Definition Possibilities

7.2.10.1 Subrange Types
.......................

   GNU Pascal supports Standard Pascal's subrange types:

     program SubrangeDemo;
     type
       MonthInt = 1 .. 12;
       Capital = 'A' .. 'Z';
       ControlChar = ^A .. ^Z;  { `^A' = `Chr (1)' is a BP extension }
     begin
     end.
   Also possible: Subranges of enumerated types:
     program EnumSubrangeDemo;
     type
       { This is an enumerated type. }
       Days = (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
     
       { This is a subrange of `Days'. }
       Working = Mon .. Fri;
     
     begin
     end.

   To increase performance, variables of such a type are aligned in a
way which makes them fastest to access by the CPU. As a result, `1 ..
12' occupies 4 bytes of storage on an Intel x86 compatible CPU.

   For the case you want to save storage at the expense of speed, GPC
provides a `packed' variant of these as an extension:

     program PackedSubrangeDemo;
     type
       MonthInt = packed 1 .. 12;
     begin
     end.

   A variable of this type occupies the shortest possible (i.e.,
addressable) space in memory - one byte on an Intel x86 compatible CPU.

   See also: *Note packed::.


File: gpc,  Node: Enumerated Types,  Next: Array Types,  Prev: Subrange Types,  Up: Type Definition Possibilities

7.2.10.2 Enumerated Types
.........................

     type
       ENUM TYPE IDENTIFIER = (NAME IDENTIFIER, ..., NAME IDENTIFIER);

   An enumerated type defines a range of elements which are referred to
by identifiers. Enumerated types are ordered by occurence in the
identifier list. So, they can be used as index types in an array
definition, and it is possible to define subranges of them. Since they
are ordered, they can be compared to one another. The intrinsic function
`Ord' applied to NAME IDENTIFIER returns the number of occurence in the
identifier list (beginning with zero), `Pred' and `Succ' return the
predecessor and successor of NAME IDENTIFIER.


   *See also* *Note Array Types::, *Note Subrange Types::, *Note Ord::,
*Note Pred::, *Note Succ::


File: gpc,  Node: Array Types,  Next: Record Types,  Prev: Enumerated Types,  Up: Type Definition Possibilities

7.2.10.3 Array Types
....................

     type
       ARRAY TYPE IDENTIFIER = array [INDEX TYPE] of ELEMENT TYPE
   or
     type
       ARRAY TYPE IDENTIFIER = array [INDEX TYPE, ..., INDEX TYPE] of ELEMENT TYPE

   The reserved word `array' defines an array type. INDEX TYPE has to
be an ordinal type, subrange type or an enumerated type, where several
index types, separated by commata, are allowed. ELEMENT TYPE is an
arbitrary type. An element of an array is accessed by ARRAY TYPE
VARIABLE [ INDEX NUMBER ]. The upper and lower index bounds can be
determined by the intrinsic functions `High' and `Low'.

     type
       IntArray = array [1 .. 20] of Integer;
       Foo      = array [(Mo, Tu, We, Th, Fr, Sa, Su)] of Char;
       Bar      = array [0 .. 9, 'a' .. 'z', (Qux, Glork1, Fred)] of Real;
       Baz1     = array [1..10] of IntArray;
       { equal (but declared differently): }
       Baz2     = array [1 .. 10, 1 .. 20] of Integer;

   *See also* *Note High::, *Note Low::


File: gpc,  Node: Record Types,  Next: Variant Records,  Prev: Array Types,  Up: Type Definition Possibilities

7.2.10.4 Record Types
.....................

     type
       RECORD TYPE IDENTIFIER = record
         FIELD IDENTIFIER : TYPE DEFINITION;
         ...
         FIELD IDENTIFIER : TYPE DEFINITION;
       end;

   or, with a variant part,

     type
       RECORD TYPE IDENTIFIER = record
         FIELD IDENTIFIER : TYPE DEFINITION;
         ...
         FIELD IDENTIFIER : TYPE DEFINITION;
       case bar: VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
       end;

   or, without a variant selector field,

     type
       RECORD TYPE IDENTIFIER = record
         FIELD IDENTIFIER : TYPE DEFINITION;
         ...
         FIELD IDENTIFIER : TYPE DEFINITION;
       case VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
       end;

   The reserved word `record' defines a structure of fields.  Records
can be `packed' to save memory usage at the expense of speed.

   The variants of a variant record share one location in memory
(inside the record) and thus can be used to emulate type casting
without violating ISO-7185 Standard Pascal.

   The reserved word `record' and record types are defined in ISO-7185
Standard Pascal.  According to ISO Pascal, the variant type must be an
identifier.  GNU Pascal, like UCSD and Borland Pascal, also allows a
subrange here.

   A record field is accessed by RECORD TYPE VARIABLE . FIELD IDENTIFIER

   See also: *Note packed::, *Note case Statement::.


File: gpc,  Node: Variant Records,  Next: Schema Types,  Prev: Record Types,  Up: Type Definition Possibilities

7.2.10.5 Variant Records
........................

   GPC supports variant records like in EP and BP. The following
construction is not allowed in Extended Pascal, but in BP and GPC:

     program BPVariantRecordDemo;
     
     type
       PersonRec = record
         Age : Integer;
       case EyeColor : (Red, Green, Blue, Brown) of
         Red, Green  : (WearsGlasses : Boolean);
         Blue, Brown : (LengthOfLashes : Integer);
       end;
     
     begin
     end.

   In EP, the variant field needs a type identifier, which, of course,
also works in GPC:

     program EPVariantRecordDemo;
     
     type
       EyeColorType = (Red, Green, Blue, Brown);
     
       PersonRec = record
         Age : Integer;
       case EyeColor : EyeColorType of
         Red, Green  : (WearsGlasses : Boolean);
         Blue, Brown : (LengthOfLashes : Integer);
       end;
     
     begin
     end.


File: gpc,  Node: Schema Types,  Next: Set Types,  Prev: Variant Records,  Up: Type Definition Possibilities

7.2.10.6 EP's Schema Types including `String'
.............................................

   Schemata are types that depend on one or more variables, called
"discriminants". They are an ISO-10206 Extended Pascal feature.

     type
       RealArray (n: Integer) = array [1 .. n] of Real;
       Matrix (n, m: PositiveInteger) = array [1 .. n, 1 .. m] of Integer;

   The type `RealArray' in this example is called a Schema with the
discriminant `n'.

   To declare a variable of such a type, write:

     var
       Foo: RealArray (42);

   The discriminants of every global or local schema variable are
initialized at the beginning of the procedure, function or program
where the schema variable is declared.

   Schema-typed variables "know" about their discriminants.
Discriminants can be accessed just like record fields:

     program Schema1Demo;
     type
       PositiveInteger = (*@@ 1 .. MaxInt *) Integer;
       RealArray (n: Integer) = array [1 .. n] of Real;
       Matrix (n, m: PositiveInteger) = array [1 .. n, 1 .. m] of Integer;
     
     var
       Foo: RealArray (42);
     
     begin
       WriteLn (Foo.n)  { yields 42 }
     end.

   Schemata may be passed as parameters. While types of schema
variables must always have specified discriminants (which may be other
variables), formal parameters (by reference or by value) may be of a
schema type without specified discriminant. In this, the actual
parameter may posses any discriminant. The discriminants of the
parameters get their values from the actual parameters.

   Also, _pointers_ to schema variables may be declared without a
discriminant:

     program Schema2Demo;
     type
       RealArray (n: Integer) = array [1 .. n] of Real;
       RealArrayPtr = ^RealArray;
     var
       Bar: RealArrayPtr;
     begin
     end.

   When applying `New' to such a pointer, you must specify the intended
value of the discriminant as a parameter:

     New (Bar, 137)

   As a GNU Pascal extension, the above can also be written as

     Bar := New (RealArrayPtr, 137)

   The allocated variable behaves like any other schema variable:

     program Schema3Demo;
     type
       RealArray (n: Integer) = array [1 .. n] of Real;
       RealArrayPtr = ^RealArray;
     var
       Bar: RealArrayPtr;
       i: Integer;
     begin
       Bar := New (RealArrayPtr, 137);
       for i := 1 to Bar^.n do
         Bar^ [i] := 42
     end.

   Since the schema variable "knows" its size, pointers to schemata can
be disposed just like other pointers:

     Dispose (Bar)

   Schemata are not limited to arrays. They can be of any type that
normally requires constant values in its definition, for instance
subrange types, or records containing arrays etc. (Sets do not yet
work.)

   References to the schema discriminants are allowed, and the `with'
statement is also allowed, so one can say:

     program SchemaWithDemo;
     type
       RealArray (n : Integer) = array [1 .. n] of Real;
     var
       MyArray : RealArray (42);
     begin
       WriteLn (MyArray.n);  { writes 42 }
       with MyArray do
         WriteLn (n);        { writes 42 }
     end.

   Finally, here is a somewhat exotic example. Here, a `ColoredInteger'
behaves just like an ordinary integer, but it has an additional
property `Color' which can be accessed like a record field.

     program SchemaExoticDemo;
     
     type
       ColorType = (Red, Green, Blue);
       ColoredInteger (Color : ColorType) = Integer;
     
     var
       Foo : ColoredInteger (Green);
     
     begin
       Foo := 7;
       if Foo.Color = red then
         Inc (Foo, 2)
       else
         Foo := Foo div 3
     end.

   An important schema is the predefined `String' schema (according to
Extended Pascal). It has one predefined discriminant identifier
`Capacity'. GPC implements the `String' schema as follows:

     type
       String (Capacity : Cardinal) = record
         Length : 0 .. Capacity;
         Chars  : packed array [1 .. Capacity + 1] of Char
       end;

   The `Capacity' field may be directly referenced by the user, the
`Length' field is referenced by a predefined string function `Length
(Str)' and contains the current string length.  `Chars' contains the
chars in the string. The `Chars' and `Length' fields cannot be directly
referenced by a user program.

   If a formal value parameter is of type `String' (with or without
discriminant), the actual parameter may be either a `String' schema, a
fixed string (character array), a single character, a string literal or
a string expression. If the actual parameter is a `String' schema, it
is copied for the parameter in the usual way. If it is not a schema, a
`String' schema is created automatically, the actual parameter is
copied to the new variable and the `Capacity' field of the new variable
is set to the length of the actual parameter.

   Actual parameters to `var' parameters of type `String' must be
`String' schemata, not string literals or character arrays.

     program StringDemo (Output);
     
     type
       SType = String (10);
       SPtr  = ^String;
     
     var
       Str  : SType;
       Str2 : String (100000);
       Str3 : String (20) value 'string expression';
       DStr : ^String;
       ZStr : SPtr;
       Len  : Integer value 256;
       Ch   : Char value 'R';
     
     { `String' accepts any length of strings }
     procedure foo (z : String);
     begin
       WriteLn ('Capacity : ', z.Capacity);
       WriteLn ('Length   : ', Length (z));
       WriteLn ('Contents : ', z);
     end;
     
     { Another way to use dynamic strings }
     procedure Bar (SLen : Integer);
     var
       LString : String (SLen);
       FooStr  : type of LString;
     begin
       LString := 'Hello world!';
       Foo (LString);
       FooStr := 'How are you?';
       Foo (FooStr);
     end;
     
     begin
       Str  := 'KUKKUU';
       Str2 := 'A longer string variable';
       New (DStr, 1000);  { Select the string Capacity with `New' }
       DStr^ := 'The maximum length of this is 1000 chars';
       New (ZStr, Len);
       ZStr^ := 'This should fit here';
       Foo (Str);
       Foo (Str2);
       Foo ('This is a constant string');
       Foo ('This is a ' + Str3);
       Foo (Ch);  { A char parameter to string routine }
       Foo ('');  { An empty string }
       Foo (DStr^);
       Foo (ZStr^);
       Bar (10000);
     end.

   In the above example, the predefined procedure `New' was used to
select the capacity of the strings. Procedure `Bar' also has a string
whose size depends of the parameter passed to it and another string
whose type will be the same as the type of the first string, using the
`type of' construct.

   All string and character types are compatible as long as the
destination string is long enough to hold the source in assignments.
If the source string is shorter than the destination, the destination
is automatically blank padded if the destination string is not of
string schema type.


File: gpc,  Node: Set Types,  Next: Pointer Types,  Prev: Schema Types,  Up: Type Definition Possibilities

7.2.10.7 Set Types
..................

     SET TYPE IDENTIFIER = set of SET ELEMENT TYPE;

   SET TYPE IDENTIFIER is a set of elements from SET ELEMENT TYPE which
is either an ordinal type, an enumerated type or a subrange type.  Set
element representatives are joined together into a set by brackets:
     [SET ELEMENT, ..., SET ELEMENT]
   `[]' indicates the empty set, which is compatible with all set types.
Note: Borland Pascal restricts the maximal set size (i.e. the range of
the set element type) to 256, GNU Pascal has no such restriction.  The
number of elements a set variable is holding can be determined by the
intrinsic set function Card (which is a GNU Pascal extension, in
Extended Pascal and Borland Pascal you can use SizeOf instead but note
the element type size in bytes, then) to the set.  There are four
intrinsic binary set operations: the union `+', the intersection `*'
and the difference `-'. The symmetric difference `><' is an Extended
Pascal extension.


   *See also* *Note Card::, *Note SizeOf::


File: gpc,  Node: Pointer Types,  Next: Procedural Types,  Prev: Set Types,  Up: Type Definition Possibilities

7.2.10.8 Pointer Types
......................

     POINTER TYPE IDENTIFIER = ^TYPE IDENTIFIER;

   A pointer of the type POINTER TYPE IDENTIFIER holds the address at
which data of the type TYPE IDENTIFIER is situated.  Unlike other
identifier declarations, where all identifiers in definition part have
to be declared before, in a pointer type declaration TYPE IDENTIFIER
may be declared after POINTER TYPE IDENTIFIER.  The data pointed to is
accessed by POINTER TYPE VARIABLE ^ . To mark an unassigned pointer,
the "NIL" constant (which stands for "not in list") has to be assigned
to it, which is compatible with all pointer types.

     type
       ItselfFoo = ^ItselfFoo;  { possible but senseless }
     
       PInt      = ^Integer;    { Pointer to an Integer }
     
       PNode     = ^TNode;      { Linked list }
       TNode     = record
         Key      : Integer;
         NextNode : PNode;
       end;
     
     var
       Foo, Bar : PInt;
     
     begin
       Foo := Bar;  { Modify address which foo is holding }
       Foo^ := 5;   { Access data foo is pointing to }
     end.

   GPC also suports pointers to procedures or function and calls
through them. This is a non-standard feature.

     program ProcPtrDemo (Output);
     
     type
       ProcPtr = ^procedure (Integer);
     
     var
       PVar : ProcPtr;
     
     procedure WriteInt (i : Integer);
     begin
       WriteLn ('Integer: ', i : 1)
     end;
     
     begin
       { Let PVar point to function WriteInt }
       PVar := &WriteInt;
     
       { Call the function by dereferencing the function pointer }
       PVar^ (12345)
     end.

   See also: *Note Pointer (Intrinsic)::.


File: gpc,  Node: Procedural Types,  Next: Object Types,  Prev: Pointer Types,  Up: Type Definition Possibilities

7.2.10.9 Procedural and Functional Types
........................................

   For procedures without a parameter list:
     PROCEDURE TYPE IDENTIFIER = procedure NAME IDENTIFIER;
   or functions:
     FUNCTION TYPE IDENTIFIER =
            function NAME IDENTIFIER: FUNCTION RESULT TYPE;

   For procedures with a parameter list:
     PROCEDURE TYPE IDENTIFIER =
            procedure NAME IDENTIFIER (PARAMETER LIST);
   or functions:
     FUNCTION TYPE IDENTIFIER =
            function NAME IDENTIFIER (PARAMETER LIST): FUNCTION RESULT TYPE;

   Procedural types can be used as procedures or functions
respectively, but also a value can be assigned to them. Procedural
types are a Borland Pascal extension.  In Borland Pascal, FUNCTION
RESULT TYPE can only be one of these types: ordinal types, enumerated
types, real types, pointer types, the intrinsic Boolean, or the
intrinsic String. In GNU Pascal every function result type for
procedural types is allowed.

   BP has procedural and functional types:

     type
       CompareFunction = function (Key1, Key2 : String) : Integer;
     
     function Sort (Compare : CompareFunction);
     begin
       ...
     end;

   Standard Pascal has procedural and functional parameters:

     function Sort (function Compare (Key1, Key2 : String) : Integer);
     begin
       ...
     end;

   Both ways have pros and cons, e.g. in BP you can save, compare,
trade, etc. procedural values, or build arrays of them, while the SP
way does not require a type declaration and prevents problems with
uninitialized or invalid pointers (which in BP will usually crash the
program).

   GPC supports both ways. An important feature of Standard Pascal (but
not BP) that GPC also supports is the possibility to pass _local_
routines as procedural or functional parameters, even if the called
routine is declared far remote. The called routine can then call the
passed local routine and it will have access to the original caller's
local variables.

     program LocalProceduralParameterDemo;
     
     procedure CallProcedure (procedure Proc);
     begin
       Proc
     end;
     
     procedure MainProcedure;
     var LocalVariable : Integer;
     
       procedure LocalProcedure;
       begin
         WriteLn (LocalVariable)
       end;
     
     begin
       LocalVariable := 42;
       CallProcedure (LocalProcedure)
     end;
     
     begin
       MainProcedure
     end.

   See also: *Note The Procedure::, *Note The Function::, *Note
Subroutine Parameter List Declaration::, *Note Procedure Call::.


File: gpc,  Node: Object Types,  Next: Type Initializers,  Prev: Procedural Types,  Up: Type Definition Possibilities

7.2.10.10 Object Types
......................

   Under construction.

   *See also* *Note OOP::


File: gpc,  Node: Type Initializers,  Next: Restricted Types,  Prev: Object Types,  Up: Type Definition Possibilities

7.2.10.11 Initial values to type denoters
.........................................

   A type may be initialized to a value of expression when it is
declared, like a variable, as in:

     program TypeVarInitDemo;
     type
       Int10   = Integer value 10;
       FooType = Real;
       MyType  = Char value Pred ('A');
       EType   = (a, b, c, d, e, f, g) value d;
     
     const
       Answer = 42;
     
     var
       ii  : Int10;                    { Value of ii set to 10 }
       ch  : MyType  value Pred ('z');
       aa  : Integer value Answer + 10;
       foo : FooType value Sqr (Answer);
       e1  : EType;                    { value set to d }
       e2  : EType value g;            { value set to g }
     begin
     end.

   Extended Pascal requires the type initializers to be constant
expressions. GPC allows any valid expression.

   Note, however, that the expressions that affect the size of storage
allocated for objects (e.g. the length of arrays) may contain variables
only inside functions or procedures.

   GPC evaluates the initial values used for the type when an
identifier is declared for that type. If a variable is declared with a
type-denoter that uses a type-name which already has an initial value
the latter initialization has precedence.

   @@ GPC does not know how to calculate constant values for math
functions in the runtime library at compile time, e.g. `Exp (Sin
(2.4567))', so you should not use these kind of expressions in object
size expressions. (Extended Pascal allows this.)


File: gpc,  Node: Restricted Types,  Prev: Type Initializers,  Up: Type Definition Possibilities

7.2.10.12 Restricted Types
..........................

   GPC supports `restricted' types, defined in Extended Pascal. A value
of a restricted type may be passed as a value parameter to a formal
parameter possessing its underlying type, or returned as the result of
a function. A variable of a restricted type may be passed as a variable
parameter to a formal parameter possessing the same type or its
underlying type. No other operations, such as accessing a component of
a restricted type value or performing arithmetic, are possible.

     program RestrictedDemo;
     
     type
       UnrestrictedRecord = record
         a : Integer;
       end;
       RestrictedRecord = restricted UnrestrictedRecord;
     
     var
       r1 : UnrestrictedRecord;
       r2 : RestrictedRecord;
       i : restricted Integer;
       k : Integer;
     
       function AccessRestricted (p : UnrestrictedRecord) : RestrictedRecord;
       var URes : UnrestrictedRecord;
       begin
         { The parameter is treated as unrestricted, even though the actual
           parameter may be a restricted object }
         URes.a := p.a;
         { It is legal to assign a return value }
         AccessRestricted := URes;
       end;
     
     begin
       r1.a := 354;
     
       { Assigning a restricted return value to a restricted object }
       { @@ Verify if this should really be allowed????? }
       r2 := AccessRestricted (r1);
     
       { Passing a restricted object to unrestericted formal parameter is ok }
       r2 := AccessRestricted (r2);
     
       {$ifdef BUG}
       { *** The following statements are illegal *** }
       r2.a := 100;    { field access }
       r1 := r2;       { assignment source is restricted }
       r2 := r1;       { assignment target is restricted }
       r1 := AccessRestricted (r2); { assigning a restricted return
                                       value to an unrestricted object }
       i  := 16#ffff;  { assignment target is restricted }
       k  := i + 2;    { arithmetic with restricted value }
       {$endif}
     end.


File: gpc,  Node: Machine-dependent Type Implementation,  Prev: Type Definition Possibilities,  Up: Data Types

7.2.11 Machine-dependent Type Implementation
--------------------------------------------

* Menu:

* Endianness::       How Integer Types are Stored on Different Machines
* Alignment::        How Variables are Placed in Memory


File: gpc,  Node: Endianness,  Next: Alignment,  Up: Machine-dependent Type Implementation

7.2.11.1 Endianness
...................

   Endianness means the order in which the bytes of a value larger than
one byte are stored in memory. This affects, e.g., integer values and
pointers while, e.g., arrays of single-byte characters are not
affected. The GPC `String' schema, however, contains `Capacity' and
`Length' fields before the character array.  These fields are integer
values larger than one byte, so the `String' schema _is_ affected by
endianness.

   Endianness depends on the hardware, especially the CPU. The most
common forms are:

   * "Little-endian"

     Little-endian machines store the least significant byte on the
     lowest memory address (the word is stored "little-end-first").

     E.g., if the 32 bit value `$deadbeef' is stored on memory address
     `$1234' on a little-endian machine, the following bytes will
     occupy the memory positions:

     Address       Value
     $1234         $ef
     $1235         $be
     $1236         $ad
     $1237         $de

     Examples for little-endian machines are Intel and compatible
     microprocessors and Alpha processors.

   * "Big-endian"

     Big-endian machines store the most significant byte on the lowest
     memory address (the word is stored "big-end-first").

     E.g., if the 32 bit value `$deadbeef' is stored on memory address
     `$1234' on a big-endian machine, the following bytes will occupy
     the memory positions:

     Address       Value
     $1234         $de
     $1235         $ad
     $1236         $be
     $1237         $ef

     Examples for big-endian machines are the Sparc and Motorola m68k
     CPU families and most RISC processors. Big-endian byte order is
     also used in the Internet protocols.


   _Note:_ There are processors which can run in both little-endian and
big-endian mode, e.g. the MIPS processors. A single program, however,
(unless it uses special machine code instructions) will always run in
one endianness.

   Under normal circumstances, programs do not need to worry about
endianness, the CPU handles it by itself. Endianness becomes important
when exchanging data between different machines, e.g.  via binary files
or over a network. To avoid problems, one has to choose the endianness
to use for the data exchange. E.g., the Internet uses big-endian data,
and most known data formats have a specified endianness (usually that
of the CPU on which the format was originally created). If you define
your own binary data format, you're free to choose the endianness to
use.

   To deal with endianness, GPC predefines the symbol
`__BYTES_LITTLE_ENDIAN__' on little-endian machines and
`__BYTES_BIG_ENDIAN__' on big-endian machines. Besides, the Run Time
System defines the constant `BytesBigEndian' as False on little-endian
machines and True on big-endian machines.

   There are also the symbols `__BITS_LITTLE_ENDIAN__',
`__BITS_BIG_ENDIAN__', `__WORDS_LITTLE_ENDIAN__',
`__WORDS_BIG_ENDIAN__' and the constants `BitsBigEndian' and
`WordsBigEndian' which concern the order of bits within a byte (e.g.,
in packed records) or of words within multiword-numbers, but these are
usually less important.

   The Run Time System also contains a number of routines to convert
endianness and to read or write data from/to binary files in a given
endianness, independent of the CPU's endianness. These routines are
described in the RTS reference (*note Run Time System::), under
`endianness'. The demo program `endiandemo.pas' contains an example on
how to use these routines.


File: gpc,  Node: Alignment,  Prev: Endianness,  Up: Machine-dependent Type Implementation

7.2.11.2 Alignment
..................

   (Under construction.)  @@ ????


File: gpc,  Node: Operators,  Next: Parameters,  Prev: Data Types,  Up: Programming

7.3 Operators
=============

   GNU Pascal supports all operators of ISO Pascal and Borland Pascal.
In addition, you can define your own operators according to the
Pascal-SC (PXSC) syntax.

* Menu:

* Built-in Operators::
* User-defined Operators::


File: gpc,  Node: Built-in Operators,  Next: User-defined Operators,  Up: Operators

7.3.1 Built-in Operators
------------------------

   The following table lists all built-in GNU Pascal operators, ordered
by precedence: `<' etc. have the lowest precedence, `not' etc. the
highest. As usual, the precedence of operators can be superseded with
parentheses.

   In an assignment statement, `:=' has lower precedence than all
operators. (This is rather obvious from the syntax of assignment
statements, and is merely noted for programmers familiar with C where
`=' is an operator.)

     <    =    >    in   <>   >=   <=
     +    -    or   +<   -<   +>   ->
     *    /    div  mod  and  shl  shr  xor  *<   /<   *>   />
     pow  **   ><
     not  &    @

   The Pascal-SC (PXSC) operators `+<', `-<', `+>', `->', `*<', `/<',
`*>', and `/>' are not yet implemented into GNU Pascal but may be
defined by the user (see below).


File: gpc,  Node: User-defined Operators,  Prev: Built-in Operators,  Up: Operators

7.3.2 User-defined Operators
----------------------------

   GNU Pascal allows the (re-)definition of binary operators according
to the Pascal-SC (PXSC) syntax. The following vector addition example
illustrates how to do this:

     program OperatorDemo;
     
     type
       Vector3 = record
         x, y, z: Real;
       end;
     
     var
       a, b, c: Vector3 = (1, 2, 3);
     
     operator + (u, v: Vector3) w: Vector3;
     begin
       w.x := u.x + v.x;
       w.y := u.y + v.y;
       w.z := u.z + v.z;
     end;
     
     begin
       c := a + b
     end.

   Between the closing parenthesis of the argument list and the result
variable (`w' in the above example), GPC allows an optional equal sign.
This is not allowed in PXSC, but it is consistent with Extended
Pascal's function return variable definitions, where the equal sign is
obligatory (but also optional in GPC).

   The argument types needn't be equal, and the name of the operator
may be an identifier instead of a known symbol. You cannot define _new_
symbols in GPC.

   The PXSC operators `+>', `+<', etc. for exact numerical calculations
currently are not implemented in GPC, but you can define them. Also,
the other real-type operators do _not_ meet the requirements of PXSC; a
module which fixes that would be a welcome contribution.


File: gpc,  Node: Parameters,  Next: Pointer Arithmetics,  Prev: Operators,  Up: Programming

7.4 Procedure And Function Parameters
=====================================

* Menu:

* Protected Parameters::  Parameters declared as `protected' or `const'
* Conformant Arrays::     The Standard way to pass arrays of variable size
* Open Arrays::           BP's alternative to Conformant Arrays


File: gpc,  Node: Protected Parameters,  Next: Conformant Arrays,  Up: Parameters

7.4.1 Parameters declared as `protected' or `const'
---------------------------------------------------

   All the following works in GPC:

     procedure Foo (protected a, b, c : Integer);    { 3 arguments }
     procedure Foo (a, b, c, protected : Integer);   { 4 arguments }
     procedure Foo (a, b, protected, c : Integer);   { 4 arguments }
     procedure Foo (protected : Integer);            { 1 argument  }
     procedure Foo (var protected : Integer);        { 1 argument  }
     procedure Foo (protected protected : Integer);  { 1 argument  }

   Furthermore, GPC supports `const', according to BP, which is
equivalent to either `protected' or `protected var', up to the
compiler's discretion.


File: gpc,  Node: Conformant Arrays,  Next: Open Arrays,  Prev: Protected Parameters,  Up: Parameters

7.4.2 The Standard way to pass arrays of variable size
------------------------------------------------------

   @@ (Under construction.)

   A feature of Standard Pascal level 1.


File: gpc,  Node: Open Arrays,  Prev: Conformant Arrays,  Up: Parameters

7.4.3 BP's alternative to Conformant Arrays
-------------------------------------------

   Borland Pascal "open array" formal parameters are implemented into
GPC. Within the function body, they have integer type index with lower
bound 0.

   In constrast to conformant arrays (which are not supported by BP),
open arrays allow any ordinal type as the index of the actual parameter
(which is useful, e.g., if you want to be able to pass values of any
enumeration type). However, they lose information about the lower bound
(which is a problem, e.g., if you want to return information to the
caller that relates to the actual array index, like the function
`IOSelect' in the Run Time System does).


File: gpc,  Node: Pointer Arithmetics,  Next: Type Casts,  Prev: Parameters,  Up: Programming

7.5 Pointer Arithmetics
=======================

   GPC allows to increment, decrement, compare, and subtract pointers
or to use them in `for' loops just like the C language.

   GPC implements the address operator `@' (a Borland Pascal extension).

     program PointerArithmeticDemo;
     var
       a: array [1 .. 7] of Char;
       p, q: ^Char;
       i: Integer;
     
     {$X+} { We need extended syntax for pointer arithmetic }
     
     begin
       for p := @A [1] to @A [7] do
         p^ := 'x';
     
       p := @A [ 7 ];
       q := @A [ 3 ];
       while p > q do
         begin
           p^ := 'y';
           Dec (p)
         end;
     
       p := @A [7];
       q := @A [3];
       i := q - p;    { yields 4 }
     end.

   Incrementing a pointer by one means to increment the address it
contains by the size of the variable it is pointing to. For typeless
pointers (`Pointer'), the address is incremented by one instead.

   Similar things hold when decrementing a pointer.

   Subtracting two pointers yields the number of variables pointed to
between both pointers, i.e. the difference of the addresses divided by
the size of the variables pointed to. The pointers must be of the same
type.


File: gpc,  Node: Type Casts,  Next: OOP,  Prev: Pointer Arithmetics,  Up: Programming

7.6 Type Casts
==============

   In some cases, especially when interfacing with other languages,
Pascal's strong typing can be an obstacle.  To temporarily circumvent
this, GPC (and other Pascal compilers) defines explicit "type casts".

   There are two kinds of type casts, value type casts and variable type
casts.

   Value type casts

   To convert a value of one data type into another type, you can use
the target type like the name of a function that is called. The value
to be converted can be a variable or an expression.

   An example:

     program TypeCastDemo;
     
     var
       Ch: Char;
       i: Integer;
     
     begin
       i := Integer (Ch)
     end.

   Another, more complicated, example:

     program TypeCst2Demo;
     
     type
       CharPtr = ^Char;
       CharArray = array [0 .. 99] of Char;
       CharArrayPtr = ^CharArray;
     
     var
       Foo1, Foo2: CharPtr;
       Bar: CharArrayPtr;
     
     {$X+} { We need extended syntax in order to use ``Succ'' on a pointer }
     
     begin
       Foo1 := CharPtr (Bar);
       Foo2 := CharPtr (Succ (Bar))
     end.

   However, because of risks involved with type casts, explained below,
you should try to avoid type casts whenever possible - and it should be
possible in most cases. For instance, the first example above could use
the built-in function "Ord" instead of the type cast:

     i := Ord (Ch);

   The assignments in the second example could be written in the
following way without any type casts:

     Foo1 := @Bar^[0];
     Foo2 := @Bar^[1];

   Value type casting only works between certain types: either between
different ordinal types (including integer types), or between different
real types, or between different pointer types. In each case, the
current value, i.e. the ordinal or numeric value or the address pointed
to, respectively, is preserved in the cast.

   Note: It is also possible to cast from an integer into a real type.
This is a consequence of the fact that integer values are generally
automatically converted to real values when needed.

   @@ ???? to dereference DOES NOT EXIST Note: In the case of pointers,
a warning is issued if the dereferenced target type requires a bigger
alignment than the dereferenced source type (see *Note Alignment::).

   Variable type casts

   It is also possible to temporarily change the type of a variable,
without converting its contents in any way. This is called variable
type casting.

   The syntax is the same as for value type casting. This can be
confusing, as the example below shows.

   The type-casted variable is still the same variable (memory location)
as the original one, just with a different type. Outside of the type
cast, the variable keeps its original type.

   There are some important differences between value and variable type
casting:

   * Variable type casting only works on variables, not on expressions.

   * The result of a variable type casting is still a variable.
     Especially, it can be used on the left side of an assignment (as a
     so-called "lvalue"), or passed by reference to a procedure.

   * No values are converted. The contents of the variable, seen as a
     raw bit pattern, are just interpreted according to the new type.
     In many cases, this does not make a big difference, e.g. the same
     ordinal values of different ordinal types have the same bit pattern
     (provided, the types have the same size), and similarly for
     different pointer types. However, there are cases where it does
     make a difference, most notably the completely different internal
     representation of integer and real types. This is demonstrated in
     the following example, admittedly a very constructed example, by
     using an integer and a real type of the same size and trying to
     cast between them.

   * Because bit patterns are just interpreted differently, the source
     and target type must have the same size. If this is not the case,
     GPC will give a warning. (@error? see below)

   * Beware: Variable type casts might have unexpected effects on
     different platforms since you cannot rely on a specific way the
     data is stored (e.g. see *Note Endianness::).


     program TrapsOfTypeCastsDemo;
     
     { Declare a real type and an integer type of the same size, and some
       variables of these types we will need. }
     
     type
       RealType = ShortReal;
       IntegerType = Integer (BitSizeOf (RealType));
     
     var
       i, i1, i2, i3, i4, i5: IntegerType;
       r, r1, r2, r3, r4: RealType;
     
     begin
     
       { First part: Casting integer into real types. }
     
       { Start with some integer value }
       i := 42;
     
       { First attempt to cast. Here, an lvalue is casted, so this must
         be a variable type cast. Therefore, the bit pattern of the value
         of i is transferred unchanged into r1 which results in a silly
         value of r1. }
       IntegerType (r1) := i;
     
       { Second try. Here we cast an expression -- though a trivial one --,
         rather than a variable. So this can only be a value type cast.
         Therefore, the numeric value is preserved, i.e. r2 = 42.0 . }
       r2 := RealType (i + 0);
     
       { Third way. In this last example, a variable is casted, and the
         result is used as an expression, not as an lvalue. So this
         could be either a value or variable type cast. However, there
         is a rule that value type casting is preferred if possible.
         So r3 will contain the correct numeric value, too. }
       r3 := RealType (i);
     
       { Of course, you do not need any casts at all here. A simple
         assignment will work because of the automatic conversion from
         integer to real types. So r4 will also get the correct result. }
       r4 := i;
     
       { Now the more difficult part: Casting real into integer types. }
     
       { Start with some real value. }
       r := 41.9;
     
       { Like the first attempt above, this one does a variable type cast,
         preserving bit patterns, and leaving a silly value in i1. }
       { RealType (i1) := r; }
     
       { The second try from above does not work, because an expression of
         type real is to be casted into an integer which is not allowed. }
       { i2 := IntegerType (r + 0); }
     
       { Third way. This looks just like the third way in the first part
         which was a value type cast.
         But -- surprise! Since value type casting is not possible from
         real into integer, this really does a variable type casting,
         and the value of i3 is silly again! This difference in behaviour
         shows some of the hidden traps in type casting. }
       i3 := IntegerType (r);
     
       { As often, it is possible to avoid type casts altogether and
         convert real types into integers easily by other means, i.e. by
         using the built-in functions ``Round'' or ``Trunc'', depending
         on the mode of rounding one wants. }
       i4 := Round (r); { 42 }
       i5 := Trunc (r); { 41 }
     
     end.

   When dealing with objects (see *Note OOP::), it is often necessary -
and safe - to cast a pointer to an object into a pointer to a more
specialized (derived) object. In future releases, GPC will provide an
operator `as' for a safer approach to this problem.

   See also: *Note absolute::, *Note Alignment::, *Note Endianness::,
*Note OOP::, *Note Ord::, *Note Chr::, *Note Round::, *Note Trunc::.


File: gpc,  Node: OOP,  Next: Compiler Directives,  Prev: Type Casts,  Up: Programming

7.7 Object-Orientated Programming
=================================

   GNU Pascal follows the object model of Borland Pascal 7.0. The BP
object extensions are almost fully implemented into GPC. This includes
inheritance, virtual and non-virtual methods, constructors,
destructors, pointer compatibility, extended `New' syntax (with
constructor call and/or as a Boolean function), extended `Dispose'
syntax (with destructor call).

   The Borland object model is different from the ISO draft, but it
will not be too difficult now to implement that too (plus the Borland
Delphi Object Extensions which are quite similar to the ISO draft).

   The syntax for an object type declaration is as follows:

     program ObjectDemo;
     
     type
       Str100 = String (100);
     
       FooParentPtr = ^fooParent;
       FooPtr = ^foo;
     
       FooParent = object
         constructor Init;
         destructor Done; virtual;
         procedure Bar (c: Real); virtual;
         function Baz (b, a, z: Char): Str100;  { not virtual }
       end;
     
       Foo = object (FooParent)
         x, y: Integer;
         constructor Init (a, b: Integer);
         destructor Done; virtual;
         procedure Bar (c: Real); virtual;  { overrides `FooParent.Bar' }
         z: Real;  { GPC extension: data fields after methods }
         function Baz: Boolean;  { new function }
       end;
     
     constructor FooParent.Init;
     begin
       WriteLn ('FooParent.Init')
     end;
     
     destructor FooParent.Done;
     begin
       WriteLn ('I''m also done.')
     end;
     
     procedure FooParent.Bar (c : Real);
     begin
       WriteLn ('FooParent.Bar (', c, ')')
     end;
     
     function FooParent.Baz (b, a, z : Char) = s : Str100;
     begin
       WriteStr (s, 'FooParent.Baz (', b, ', ', a, ', ', z, ')')
     end;
     
     constructor Foo.Init (a, b : Integer);
     begin
       inherited Init;
       x := a;
       y := b;
       z := 3.4;
       FooParent.Bar (1.7)
     end;
     
     destructor Foo.Done;
     begin
       WriteLn ('I''m done.');
       inherited Done
     end;
     
     procedure Foo.Bar (c: Real);
     begin
       WriteLn ('Foo.Bar (', c, ')')
     end;
     
     function Foo.Baz: Boolean;
     begin
       Baz := True
     end;
     
     var
       Ptr: FooParentPtr;
     
     begin
       Ptr := New (FooPtr, Init (2, 3));
       Ptr^.Bar (3);
       Dispose (Ptr, Done);
       New (Ptr, Init);
       with Ptr^ do
         WriteLn (Baz ('b', 'a', 'z'))
     end.

   Remarks:

   * Data fields and methods can be mixed.

   * GPC currently does not support `private' declarations and such.
     These directives are syntactically accepted but ignored.

   * Constructors and destructors are ordinary functions, internally.
     When a constructor is called, GPC creates some inline code to
     initialize the object; destructors do nothing special.

   * Currently, the compiler does not check whether all declared methods
     are really implemented. Unimplemented methods will produce linking
     errors when they are called or if they are virtual.


   A pointer to `FooParent' may be assigned the address of a `Foo'
object. A `FooParent' formal `var' parameter may get a `Foo' object as
the actual parameter. In such cases, a call to a `virtual' method calls
the child's method, whereas a call to a non-`virtual' method selects
the parent's one:

     var
       MyFooParent: FooParentPtr;
       SomeFoo: Foo;
     
     [...]
     
       SomeFoo.Init (4, 2);
       MyFooParent := @SomeFoo;
       MyFooParent^.bar (3.14);  { calls `foo.bar' }
       MyFooParent^.baz ('b', 'a', 'z');  { calls `fooParent.baz' }
       if SomeFoo.baz then  { calls `foo.baz' }
         WriteLn ('Baz!');

   In a method, an overwritten method of a parent object can be called
either prefixing it with the parent type name, or using the keyword
`inherited':

     procedure Foo.Bar (c : Real);
     begin
       z := c;
       inherited bar (z)  { or: FooParent.Bar (z) }
     end;

   Use `FooParent.bar (z)' if you want to be sure that _this_ method is
called, even if somebody decides not to derive `foo' directly from
`fooParent' but to have some intermediate object. If you want to call
the method `bar' of the immediate parent - whether it be `fooParent' or
whatever - use `inherited bar (z)'.

   To allocate an object on the heap, use `New' in one of the following
manners:

     var
       MyFoo: FooPtr;
     
       [...]
     
       New (MyFoo, Init (4, 2));
     
       MyFooParent := New (FooPtr, Init (4, 2))

   The second possibility has the advantage that `MyFoo' needn't be a
`FooPtr' but can also be a `FooParentPtr', i.e. a pointer to an
ancestor of `foo'.

   Destructors can and should be called within Dispose:

     Dispose (MyFooParent, Fini)


File: gpc,  Node: Compiler Directives,  Next: Library Routines,  Prev: OOP,  Up: Programming

7.8 Compiler Directives And The Preprocessor
============================================

   GPC, like UCSD Pascal and BP, treats comments beginning with a `$'
immediately following the opening `{' or `(*' as a compiler directive.
As in Borland Pascal, `{$...}' and `(*$...*)' are equivalent. When a
single character plus a `+' or `-' follows, this is also called a
compiler switch.  All of these directives are case-insensitive (but
some of them have case-sensitive arguments). Directives are local and
can be changed during one compilation (except include files etc. where
this makes no sense).

   In general, compiler directives are compiler-dependent. (E.g., only
the include directive `{$I FileName}' is common to UCSD and BP.)
Because of BP's popularity, GPC supports all of BP's compiler
directives (and ignores those that are unnecessary on its platforms -
these are those not listed below), but it knows a lot more directives.

   Some BP directives are - of course not by chance - just an
alternative notation for C preprocessor directives. But there are
differences: BP's "conditional" definitions (`{$define Foo}') go into
another name space than the program's definitions. Therefore you can
define conditionals and check them via `{$ifdef Foo}', but the program
will not see them as an identifier `Foo', so macros do not exist in
Borland Pascal.

   GPC does support macros, but disables this feature when the
`--no-macros' option or the dialect option `--borland-pascal' or
`--delphi' is given, to mimic BP's behaviour. Therefore, the following
program will react differently when compiled with GPC either without
special options or with, e.g., the `--borland-pascal' option (and in
the latter case, it behaves the same as when compiled with BP).

     program MacroDemo;
     
     const Foo = 'Borland Pascal';
     
     {$define Foo 'Default'}
     
     begin
       WriteLn (Foo)
     end.

   Of course, you should not rely on such constructs in your programs.
To test if the program is compiled with GPC, you can test the `__GPC__'
conditional, and to test the dialect used in GPC, you can test
conditionals like `__BORLAND_PASCAL__'.

   In general, almost every GPC specific command line option (*note GPC
Command Line Options::) can be turned into a compiler directive
(exceptions are those options that contain directory names, such as
`--unit-path', because they refer to the installation on a particular
system, and therefore should be set system-wide, rather than in a
source file):

     --foo       {$foo}
     --no-foo    {$no-foo}
     -Wbar       {$W bar}     { note the space after the `W' }
     -Wno-bar    {$W no-bar}

   The following table lists some such examples as well as all those
directives that do not correspond to command-line options or have
syntactical alternatives (for convenience and/or BP compatibility).

     --[no-]short-circuit   $B+ $B- like in Borland Pascal:
                                    $B- means short-circuit Boolean
                                    operators; $B+ complete evaluation
     
     --[no-]io-checking     $I+ $I- like in Borland Pascal:
                                    enable/disable I/O checking
     
     --[no-]stack-checking  $S+ $S- like in Borland Pascal:
                                    enable/disable stack checking
     
     --[no-]typed-address   $T+ $T- like in Borland Pascal:
                                    make the result of the address
                                    operator and the Addr function a
                                    typed or untyped pointer
     
     -W[no-]warnings        $W+ $W- enable/disable warnings. Note: in
                                    `--borland-pascal' mode, the
                                    short version is disabled because
                                    $W+/$W- has a different meaning in
                                    Borland Pascal (which can safely be
                                    ignored in GPC), but the long version
                                    is still available.
     
     --[no-]extended-syntax $X+ $X- mostly like in Borland Pascal:
                                    enable/disable extended syntax
                                    (ignore function return values,
                                    operator definitions, `PChar',
                                    pointer arithmetic, ...)
     
     --borland-pascal               disable or warn about GPC features
     --extended-pascal              not supported by the standard or
     --pascal-sc                    dialect given, do not warn about its
     etc.                           ``dangerous'' features (especially BP).
                                    The dialect can be changed during one
                                    compilation via directives like,
                                    e.g., `{$borland-pascal}'.
     
     {$M Hello!}                    write message `Hello!' to
                                    standard error during compilation. In
                                    `--borland-pascal' mode, it is
                                    ignored it if only numbers follow
                                    (for compatibility to Borland
                                    Pascal's memory directive)
     
     {$define FOO}                  like in Borland Pascal:
     or                             define FOO (for conditional compilation)
     {$CIDefine FOO}                (case-insensitively)
     
     --cidefine=FOO                 the same on the command line
     
     {$CSDefine FOO}                define FOO case-sensitively
     
     -D FOO                         the same on the command line
     or                             Note: `--define' on the command
     --csdefine=FOO                 line is case-sensitive like in GCC,
     or                             but `{$define}' in the source code
     --define=FOO                   is case-insensitive like in BP
     
     {$define loop while True do}   define `loop' to be `while True do'
     or                             as a macro like in C. The name of the
     {$CIDefine loop ...}           macro is case-insensitive. Note:
                                    Macros are disabled in
                                    `--borland-pascal' mode because BP
                                    doesn't support macros.
     
     --cidefine="loop=..."          the same on the command line
     
     {$CSDefine loop ...}           define a case-sensitive macro
     
     --csdefine="loop=..."          the same on the command line
     or
     --define="loop=..."
     
     {$I FileName}                  like in Borland Pascal:
                                    include `filename.pas'
                                    (the name is converted to lower case)
     
     {$undef FOO}                   like in Borland Pascal: undefine FOO
     
     {$ifdef FOO}                   conditional compilation
       ...                          (like in Borland Pascal).
     {$else}                        Note: GPC predefines the symbol
       ...                          `__GPC__' (with two leading
     {$endif}                       and trailing underscores).
     
     {$include "filename.pas"}      include (case-sensitive)
     
     {$include <filename.pas>}      the same, but don't search in the
                                    current directory
   ...and all the other C preprocessor directives.

   You also can use the preprocessor directives in C style, e.g.
`#include', but this is deprecated because of possible confusion with
Borland Pascal style `#42' character constants.  Besides, in the Pascal
style, e.g. `{$include "foo.bar"}', there may be more than one
directive in the same line.


File: gpc,  Node: Library Routines,  Next: Other Languages,  Prev: Compiler Directives,  Up: Programming

7.9 Routines Built-in or in the Run Time System
===============================================

   In this section we describe the routines and other declarations that
are built into the compiler or part of the Run Time System, sorted by
topics.

* Menu:

* File Routines::
* String Operations::
* Accessing Command Line Arguments::
* Memory Management Routines::
* Operations for Integer and Ordinal Types::
* Complex Number Operations::
* Set Operations::
* Date And Time Routines::


File: gpc,  Node: File Routines,  Next: String Operations,  Up: Library Routines

7.9.1 File Routines
-------------------

   Extended Pascal treats files quite differently from Borland Pascal.
GPC supports both forms, even in mixed ways, and provides many
extensions.

   @@ A lot missing here

   * An example of getting the size of a file (though a `FileSize'
     function is already built-in).

          function FileSize(filename : String) : LongInt;
          var
            f : bindable file [0..MaxInt] of char;
            b : BindingType;
          begin
            unbind(f);
            b := binding (f);
            b.Name := filename;
            bind(f, b);
            b := binding(f);
            SeekRead(f, 0);
            if empty(f)
              then  file_size := 0
              else  file_size := LastPosition(f) + 1;
            unbind(f);
          end;

     Prospero's Extended Pascal has a bug in this case. Replace the
     MaxInt in the type definition of f by a sufficiently large
     integer. GNU Pascal works correct in this case.

   * GPC implements "lazy" text file I/O, i.e. does a `Put' as soon as
     possible and a `Get' as late as possible. This should avoid most
     of the problems sometimes considered to be the most stupid feature
     of Pascal. When passing a file buffer as parameter the buffer is
     validated when the parameter is passed.

   * GPC supports direct access files. E.g., declaring a type for a
     file that contains 100 integers.

          program DirectAccessFileDemo;
          type
            DFile = file [1 .. 100] of Integer;
          var
            F : DFile;
            P, N : 1 .. 100;
          begin
            Rewrite (F);
            P := 42;
            N := 17;
            SeekWrite (F, P);
            Write (F, N)
          end.

     The following direct access routines may be applied to a direct
     access file:

    `SeekRead   (F, N);      { Open file in inspection mode, seek to record N }'

    `SeekWrite  (F, N);      { Open file in generation mode, seek to record N }'

    `SeekUpdate (F, N);      { Open file in update mode, seek to record N }'

    `Update (F);             { Writes F^, position not changed. F^ kept. }'

    `p := Position (F);      { Return current record number }'

    `p := LastPosition (F);  { Return the last record number in file }'
     If the file is open for inspection or update, `Get' may be applied.
     If the file is open for generation or update, `Put' may be applied.

   * In BP, you can associate file variables with files using the
     `Assign' procedure which GPC supports.

          program AssignTextDemo;
          var
            t : Text;
            Line : String (4096);
          begin
            Assign (t, 'mytext.txt');
            Reset (t);
            while not EOF (t) do
              begin
                ReadLn (t, Line);
                WriteLn (Line)
              end
          end.

   * In Extended Pascal, files are considered entities external to your
     program. External entities, which don't need to be files, need to
     be bound to a variable your program. Any variable to which external
     entities can be bound needs to be declared `bindable'. Extended
     Pascal has the `Bind' function that binds a variable to an
     external entity as well as `Unbind' to undo a binding and the
     function `Binding' to return the current binding of a variable.

     GPC supports these routines when applied to files. The compiler
     will reject binding of other object types.

     Only the fields `Bound' and `Name' of the predefined record type
     `BindingType' are required by Extended Pascal.  Additionally, GPC
     implements some extensions. For the full definition of
     `BindingType', see *Note BindingType::.

     The following is an example of binding:

          program BindingDemo (Input, Output, f);
          
          var
            f : bindable Text;
            b : BindingType;
          
          procedure BindFile (var f : Text);
          var
            b : BindingType;
          begin
            Unbind (f);
            b := Binding (f);
            repeat
              Write ('Enter a file name: ');
              ReadLn (b.Name);
              Bind (f, b);
              b := Binding (f);
              if not b.Bound then
                WriteLn ('File not bound -- try again.')
            until b.Bound
          end;
          
          begin
            BindFile (f);
            { Now the file f is bound to an external file. We can use the
              implementation defined fields of BindingType to check if the
              file exists and is readable, writable or executable. }
            b := Binding (f);
            Write ('The file ');
            if b.Existing then
              WriteLn ('exists.')
            else
              WriteLn ('does not exist.');
            Write ('It is ');
            if not b.Readable then Write ('not ');
            Write ('readable, ');
            if not b.Writable then Write ('not ');
            Write ('writable and ');
            if not b.Executable then Write ('not ');
            WriteLn ('executable.')
          end.


   Note that Prospero's Pascal defaults to creating the file if it does
not exists! You need to use Prospero's local addition of setting
`b.Existing' to `True' to work-around this. GPC does not behave like
this.


File: gpc,  Node: String Operations,  Next: Accessing Command Line Arguments,  Prev: File Routines,  Up: Library Routines

7.9.2 String Operations
-----------------------

   In the following description, `s1' and `s2' may be arbitrary string
expressions, `s' is a variable of string type.

`WriteStr (s, write-parameter-list)'

`ReadStr (s1, read-parameter-list)'
     Write to a string and read from a string.  The parameter lists are
     identical to `Write'/`Read' from `Text' files. The semantics is
     closely modeled after file I/O.

`Index (s1, s2)'
     If `s2' is empty, return 1 else if `s1' is empty return 0 else
     returns the position of `s2' in `s1' (an integer).

`Length (s1)'
     Return the length of `s1' (an integer from `0 .. s1.Capacity').

`Trim (s1)'
     Returns a new string with spaces stripped of the end of `s'.

`SubStr (s1, i)'

`SubStr (s1, i, j)'
     Return a new substring of `s1' that contains `j' characters
     starting from `i'. If `j' is missing, return all the characters
     starting from `i'.

`EQ (s1, s2)'

`NE (s1, s2)'

`LT (s1, s2)'

`LE (s1, s2)'

`GT (s1, s2)'

`GE (s1, s2)'
     Lexicographic comparisons of `s1' and `s2'. Returns a boolean
     result. Strings are not padded with spaces.

`s1 =  s2'

`s1 <> s2'

`s1 <  s2'

`s1 <= s2'

`s1 >  s2'

`s1 >= s2'
     Lexicographic comparisons of `s1' and `s2'. Returns a boolean
     result. The shorter string is blank padded to length of the longer
     one, but only in `--extended-pascal' mode.

   GPC supports string catenation with the `+' operator or the `Concat'
function. All string-types are compatible, so you may catenate any
chars, fixed length strings and variable length strings.

     program ConcatDemo (Input, Output);
     
     var
       Ch   : Char;
       Str  : String (100);
       Str2 : String (50);
       FStr : packed array [1 .. 20] of Char;
     
     begin
        Ch := '$';
        FStr := 'demo';  { padded with blanks }
        Write ('Give me some chars to play with: ');
        ReadLn (Str);
        Str := '^' + 'prefix:' + Str + ':suffix:' + FStr + Ch;
        WriteLn (Concat ('Le', 'ng', 'th'), ' = ', Length (Str));
        WriteLn (Str)
     end.

   Note: The length of strings in GPC is limited only by the range of
`Integer' (at least 32 bits, i.e., 2 GB), or the available memory,
whichever is smaller. :-)

   When trying to write programs portable to other EP compilers, it is
however save to assume a limit of about 32 KB. At least Prospero's
Extended Pascal compiler limits strings to 32760 bytes. DEC Pascal
limits strings to 65535 bytes.


File: gpc,  Node: Accessing Command Line Arguments,  Next: Memory Management Routines,  Prev: String Operations,  Up: Library Routines

7.9.3 Accessing Command Line Arguments
--------------------------------------

   GPC supports access to the command line arguments with the BP
compatible `ParamStr' and `ParamCount' functions.

   * `ParamStr [0]' is the program name,

   * `ParamStr [1] .. ParamStr [ParamCount]' are the arguments.

   The program below accesses the command line arguments.

     program CommandLineArgumentsDemo (Output);
     
     var
       Counter : Integer;
     
     begin
       WriteLn ('This program displays command line arguments one per line.');
       for Counter := 0 to ParamCount do
         WriteLn ('Command line argument #', Counter, ' is `',
                  ParamStr (Counter), '''')
     end.


File: gpc,  Node: Memory Management Routines,  Next: Operations for Integer and Ordinal Types,  Prev: Accessing Command Line Arguments,  Up: Library Routines

7.9.4 Memory Management Routines
--------------------------------

   Besides the standard `New' and `Dispose' routines, GPC also allows
BP style dynamic memory management with `GetMem' and `FreeMem':

     GetMem (MyPtr, 1024);
     FreeMem (MyPtr, 1024);

   GPC also supports function style call to `GetMem':

     MyPtr := GetMem (1024);

   (see also: `New' in context of Object Orientated Programming)

   One somehow strange feature of Borland is *not* supported: You
cannot free parts of a variable with `FreeMem', while the rest is still
used and can be freed later by another `FreeMem' call:

     program PartialFreeMemDemo;
     
     type
       Vector = array [0 .. 1023] of Integer;
       VecPtr = ^Vector;
     
     var
       p, q : VecPtr;
     
     begin
       GetMem (p, 1024 * SizeOf (Integer));
       q := VecPtr (@p^ [512]);
     
       { ... }
     
       FreeMem (p, 512 * SizeOf (Integer));
     
       { ... }
     
       FreeMem (q, 512 * SizeOf (Integer));
     end.


File: gpc,  Node: Operations for Integer and Ordinal Types,  Next: Complex Number Operations,  Prev: Memory Management Routines,  Up: Library Routines

7.9.5 Operations for Integer and Ordinal Types
----------------------------------------------

   * Bit manipulations: The BP style bit shift operators `shl' and
     `shr' exist in GPC as well as bitwise `and', `or', `xor' and `not'
     for integer values.

          2#100101 and (1 shl 5) = 2#100000

     GPC also supports `and', `or', `xor' and `not' as procedures:

          program BitOperatorProcedureDemo;
          var x : Integer;
          begin
            x := 7;
            and (x, 14);  { sets x to 6 }
            xor (x, 3);   { sets x to 5 }
          end.

   * Succ, Pred: The standard functions `Succ' and `Pred' exist in GPC
     and accept a second parameter.

   * Increment, decrement: The BP built-in Procedures `Inc' and `Dec'
     exist in GPC.

          program IncDecDemo;
          var
            i : Integer;
            c : Char;
          begin
            Inc (i);     { i := i + 1; }
            Dec (i, 7);  { i := i - 7; }
            Inc (c, 3);  { c := Succ (c, 3); }
          end.

   * `Min', `Max': These are a GNU extension and work for reals as well
     as for ordinal types. Mixing reals and integers is okay, the
     result is real then.



File: gpc,  Node: Complex Number Operations,  Next: Set Operations,  Prev: Operations for Integer and Ordinal Types,  Up: Library Routines

7.9.6 Complex Number Operations
-------------------------------

   @@ A lot missing here

   * binary operators `+, -, *, /' and unary `-, +'

   * exponentiation operators (`pow' and `**')

   * functions (`Sqr, ArcTan, SqRt, Exp, Ln, Sin, Cos')

   * number info with `Re, Im' and `Arg' functions

   * numbers constructed by `Cmplx' or `Polar'

   The following sample programs illustrates most of the `Complex' type
operations.

     program ComplexOperationsDemo (Output);
     
     var
       z1, z2 : Complex;
       Len, Angle : Real;
     
     begin
       z1 := Cmplx (2, 1);
       WriteLn;
       WriteLn ('Complex number z1 is: (', Re (z1) : 1, ',', Im (z1) : 1, ')');
       WriteLn;
       z2 := Conjugate(z1); { GPC extension }
       WriteLn ('Conjugate of z1 is: (', Re (z2) : 1, ',', Im (z2) : 1, ')');
       WriteLn;
       Len   := Abs (z1);
       Angle := Arg (z1);
       WriteLn ('The polar representation of z1 is: Length=', Len : 1,
                ', Angle=', Angle : 1);
       WriteLn;
       z2 := Polar (Len, Angle);
       WriteLn ('Converting (Length, Angle) back to (x, y) gives: (',
                Re (z2) : 1, ',', Im (z2) : 1, ')');
       WriteLn;
       WriteLn ('The following operations operate on the complex number z1');
       WriteLn;
       z2 := ArcTan (z1);
       WriteLn ('arctan (z1) = (', Re (z2), ', ', Im (z2), ')');
       WriteLn;
       z2 := z1 ** 3.141;
       WriteLn ('z1 ** 3.141 =', Re (z2), ', ', Im (z2), ')');
       WriteLn;
       z2 := Sin (z1);
       WriteLn ('Sin (z1) = (', Re (z2), ', ', Im (z2), ')');
       WriteLn ('(Cos, Ln, Exp, SqRt and Sqr exist also.)');
       WriteLn;
       z2 := z1 pow 8;
       WriteLn ('z1 pow 8 = (', Re (z2), ', ', Im (z2), ')');
       WriteLn;
       z2 := z1 pow (-8);
       WriteLn ('z1 pow (-8) = (', Re (z2), ', ', Im (z2), ')');
     end.


File: gpc,  Node: Set Operations,  Next: Date And Time Routines,  Prev: Complex Number Operations,  Up: Library Routines

7.9.7 Set Operations
--------------------

   @@ A lot missing here

   GPC supports Standard Pascal set operations. In addition it supports
the Extended Pascal set operation symmetric difference

   (`set1 >< set2') operation whose result consists of those elements
which are in exactly one of the operannds.

   It also has a function that counts the elements in the set: `a :=
Card (set1)'.


File: gpc,  Node: Date And Time Routines,  Prev: Set Operations,  Up: Library Routines

7.9.8 Date And Time Routines
----------------------------

`procedure GetTimeStamp (var t : TimeStamp);'

`function Date (t : TimeStamp) : packed array [1 .. DateLength] of Char;'

`function Time (t : TimeStamp) : packed array [1 .. TimeLength] of Char;'
   `DateLength' and `TimeLength' are implementation dependent constants.

   `GetTimeStamp (t)' fills the record `t' with values. If they are
valid, the Boolean flags are set to True.

   `TimeStamp' is a predefined type in the Extended Pascal standard. It
may be extended in an implementation, and is indeed extended in GPC.
For the full definition of `TimeStamp', see *Note TimeStamp::.


File: gpc,  Node: Other Languages,  Next: Notes for Debugging,  Prev: Library Routines,  Up: Programming

7.10 Interfacing with Other Languages
=====================================

   The standardized GNU compiler back-end makes it relatively easy to
share libraries between GNU Pascal and other GNU compilers. On
Unix-like platforms (_not_ on Dos-like platforms), the GNU compiler
back-end usually complies to the standards defined for that system, so
communication with other compilers should be easy, too.

   In this chapter we discuss how to import libraries written in other
languages, and how to import libraries written in GNU Pascal from other
languages. While the examples will specialize to compatibility to GNU
C, generalization is straightforward if you are familiar with the other
language in question.

* Menu:

* Importing Libraries from Other Languages::
* Exporting GPC Libraries to Other Languages::


File: gpc,  Node: Importing Libraries from Other Languages,  Next: Exporting GPC Libraries to Other Languages,  Up: Other Languages

7.10.1 Importing Libraries from Other Languages
-----------------------------------------------

   To use a function written in another language, you need to provide
an external declaration for it - either in the program, or in the
interface part of a unit, or an interface module.

   Let's say you want to use the following C library from Pascal:

     File `callc.c':
     
     #include <unistd.h>
     #include "callc.h"
     
     int foo = 1;
     
     void bar (void)
     {
       sleep (foo);
     }

     File `callc.h':
     
     /* Actually, we wouldn't need this header file, and could instead
        put these prototypes into callc.c, unless we want to use callc.c
        also from other C source files. */
     
     extern int foo;
     extern void bar (void);

   Then your program can look like this:

     program CallCDemo;
     
     {$L callc.c}  { Or: `callc.o' if you don't have the source }
     
     var
       foo : Integer; asmname 'foo'; external;
     
     procedure Bar; asmname 'bar';
     
     begin
       foo := 42;
       Bar
     end.

   Or, if you want to provide a `CallCUnit' unit:

     unit CallCUnit;
     
     interface
     
     var
       foo : Integer; asmname 'foo'; external;
     
     procedure Bar; asmname 'bar';
     
     implementation
     
     {$L callc.c}  { Or: `callc.o' if you don't have the source }
     
     end.

     program CallCUDemo;
     
     uses CallCUnit;
     
     begin
       foo := 42;
       Bar
     end.

   You can either link your program manually with `callc.o' or put a
compiler directive `{$L callc.o}' into your program or unit, and then
GPC takes care of correct linking. If you have the source of the C
library (you always have it if it is Free Software), you can even write
`{$L callc.c}' in the program (like above). Then GPC will also link
with `callc.o', but in addition GPC will run the C compiler whenever
`callc.c' has changed if `--automake' is given, too.

   While it is convenient for most applications, there is no must to
give the C function `bar' the name `Bar' in Pascal; you can name it as
you like.

   For external functions completely written in lowercase there is the
shortcut `C' or `C_language' for `asmname 'bar''.  For external
functions written with one uppercase letter and the others in
lowercase, you can use `external' or `extern' instead of `asmname
'Bar''.  Since GPC internally converts all identifiers to this notation,
`external' is the natural choice when importing other Pascal functions.

   *Caution:* This syntax (`C', `asmname' and such) is subject to
change.

   It is important that data types of both languages are mapped
correctly onto each other.  C's `int', for instance, translates to GPC's
`Integer', and C's `unsigned long' to `MedCard'.  For a complete list
of integer types with their C counterparts, see *Note Integer Types::.

   In some cases it can be reasonable to translate a C pointer
parameter to a Pascal `var' parameter.  Since const parameters in GPC
can be passed by value _or_ by reference internally, possibly depending
on the system, `const foo *' parameters to C functions _cannot_
reliably declared as `const' in Pascal.  However, Extended Pascal's
`protected var' can be used since this guarantees passing by reference.

   Some libraries provide a `main' function and require your program's
"main" to be named differently. To achive this with GPC, invoke it with
an option `--gpc-main="GPCmain"' (where `GPCmain' is an example how you
might want to name the program). You can also write it into your source
as a directive `{$gpc-main="GPCmain"}'.


File: gpc,  Node: Exporting GPC Libraries to Other Languages,  Prev: Importing Libraries from Other Languages,  Up: Other Languages

7.10.2 Exporting GPC Libraries to Other Languages
-------------------------------------------------

   The `.o' files produced by GPC are in the same format as those of all
other GNU compilers, so there is no problem in writing libraries for
other languages in Pascal. To use them, you will need to write kind of
interface - a header file in C. However there are some things to take
into account, especially if your Pascal unit exports objects:

   * By default, GPC capitalizes the first letter (only) of each
     identifier, so `procedure FooBAR' must be imported as `extern void
     Foobar()' from C.

   * If you want to specify the external name explicitly, use `asmname':

          procedure FooBAR; asmname 'FooBAR';
          { Works like a `forward' declaration }
          
          procedure FooBAR;
          begin
            WriteLn ('FooBAR')
          end;

     This one can be imported from C with `extern void FooBar()'.

   * Objects are "records" internally.  They have an implicit `vmt'
     field which contains a pointer to the "virtual method table".
     This table is another record of the following structure:

          type
            VMT = record
              ObjectSize: PtrInt;     { Size of object in bytes }
              NegObjectSize: PtrInt;  { Negated size }
              Methods: array [1 .. n] of procedure;
                { Pointers to the virtual methods. The entries are of the
                   repective procedure or function types. }
            end;

     You can call a virtual method of an object from C if you
     explicitly declare this `struct' and explicitly dereference the
     `Fun' array.  The VMT of an object `FooBAR' is an external (in C
     sense) variable `vmt_Foobar' internally.

   * Methods of objects are named `Myobject_Mymethod' (with exactly two
     capital letters) internally.

   * If you want to put a program in a library for some reason, and you
     want to give the `main' program an internal name different from
     `main', call GPC with the command-line option
     `--gpc-main="GPCmain"' (see the previous subsection).



File: gpc,  Node: Notes for Debugging,  Next: Run Time System,  Prev: Other Languages,  Up: Programming

7.11 Notes for Debugging
========================

   * The GNU debugger, `gdb', does not yet understand Pascal sets,
     files or subranges. Now `gdb' allows you to debug these things,
     even though it does not yet understand some stabs.

   * Forward referencing pointers generate debug info that appears as
     generic pointers.

   * No information of `with' statements is currently given to the
     debugger.

   * When debugging, please note that the Initial Letter In Each
     Identifier Is In Upper Case And The Rest Are In Lower Case, unless
     explicitly overriden with `asmname' (*note asmname::) or a similar
     directive. This is to reduce name clashes with `libc.a' and other
     possible libraries.

   * All visible GPC Run Time System routines have linker names starting
     with `_p_'.

   * The linker name of the main program is `pascal_main_program'.
     This is done because ISO Standard wants to have the program name in
     a separate name space.


File: gpc,  Node: Run Time System,  Next: GPC Units,  Prev: Notes for Debugging,  Up: Programming

7.12 Pascal declarations for GPC's Run Time System
==================================================

   Below is a Pascal source of the declarations in GPC's Run Time
System (RTS). A file `gpc.pas' with the same contents is included in
the GPC distribution in a `units' subdirectory of the directory
containing `libgcc.a'. (To find out the correct directory for your
installation, type `gpc --print-file-name=units' on the command line.)

     {
     Pascal declarations of the GPC Run Time System that are visible to
     each program.
     
     This unit contains Pascal declarations of many RTS routines which
     are not built into the compiler and can be called from programs.
     Don't copy the declarations from this unit into your programs, but
     rather include this unit with a `uses' statement. The reason is that
     the internal declarations, e.g. the `asmnames', may change, and this
     unit will be changed accordingly. @@In the future, this unit might
     be included into every program automatically, so there will be no
     need for a `uses' statement to make the declarations here available.
     
     Note about `protected var' parameters:
     Since const parameters in GPC may be passed by value *or* by
     reference internally, possibly depending on the system, `const foo*'
     parameters to C functions *cannot* reliably declared as `const' in
     Pascal. However, Extended Pascal's `protected var' can be used since
     this guarantees passing by reference.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     
     module GPC interface;
     
     export
       GPC = all;
       GPC_SP = (eread (*@@not really, but an empty export doesn't
       work*));
       GPC_EP = (eread (*@@not really, but an empty export doesn't
       work*));
       GPC_BP = (MaxLongInt, ExitCode, ErrorAddr, Pos);
       GPC_Delphi = (MaxLongInt, Int64, EConvertError, ExitCode,
                     ErrorAddr, Pos, SetString, StringOfChar, TextFile,
                     AssignFile, CloseFile);
     
     const
       MaxLongInt = High (LongInt);
     
       { Maximum size of a variable }
       MaxVarSize = MaxInt div 8;
     
     type
       Int64 = Integer (64);
     
     { ====================== MEMORY MANAGEMENT ======================= }
     
     { Heap manipulation, from heap.c }
     
     { GPC implements both Mark/Release and Dispose. Both can be mixed
       freely
       in the same program. Dispose should be preferred, since it's
       faster. }
     
     { C heap management routines. NOTE: if Release is used anywhere in
       the program, CFreeMem and CReAllocMem may not be used for pointers
       that were not allocated with CGetMem. }
     function  CGetMem     (Size : SizeType) : Pointer; asmname 'malloc';
     procedure CFreeMem    (aPointer : Pointer); asmname 'free';
     function  CReAllocMem (aPointer : Pointer; NewSize : SizeType) :
       Pointer; asmname 'realloc';
     
     type
       GetMemType     = ^function (Size : SizeType) : Pointer;
       FreeMemType    = ^procedure (aPointer : Pointer);
       ReAllocMemType = ^function (aPointer : Pointer; NewSize :
       SizeType) : Pointer;
     
     { These variables can be set to user-defined routines for memory
       allocation/deallocation. GetMemPtr may return nil when
       insufficient memory is available. GetMem/New will produce a
       runtime error then. }
     var
       GetMemPtr     : GetMemType; asmname '_p_getmem_ptr'; external;
       FreeMemPtr    : FreeMemType; asmname '_p_freemem_ptr'; external;
       ReAllocMemPtr : ReAllocMemType; asmname '_p_reallocmem_ptr';
       external;
     
       { Points to the lowest byte of heap used }
       HeapBegin : Pointer; asmname '_p_heap_begin'; external;
     
       { Points to the highest byte of heap used }
       HeapHigh  : Pointer; asmname '_p_heap_high'; external;
     
     const
       UndocumentedReturnNil = Pointer (- 1);
     
     { Returns the number of pointers that would be released. aPointer
       must
       have been marked with Mark. For an example of its usage, see the
       HeapMon unit. }
     function  ReleaseCount (aPointer : Pointer) : Integer;
       asmname '_p_releasecount';
     
     procedure ReAllocMem (var aPointer : Pointer; NewSize : SizeType);
       asmname '_p_reallocmem';
     
     { Routines to handle endianness, from endian.pas }
     
     { Boolean constants about endianness and alignment }
     
     const
       BitsBigEndian  = {$ifdef __BITS_LITTLE_ENDIAN__} False
                        {$else}{$ifdef __BITS_BIG_ENDIAN__} True
                        {$else}{$error Bit endianness is not defined!}
                        {$endif}{$endif};
     
       BytesBigEndian = {$ifdef __BYTES_LITTLE_ENDIAN__} False
                        {$else}{$ifdef __BYTES_BIG_ENDIAN__} True
                        {$else}{$error Byte endianness is not defined!}
                        {$endif}{$endif};
     
       WordsBigEndian = {$ifdef __WORDS_LITTLE_ENDIAN__} False
                        {$else}{$ifdef __WORDS_BIG_ENDIAN__} True
                        {$else}{$error Word endianness is not defined!}
                        {$endif}{$endif};
     
       NeedAlignment  = {$ifdef __NEED_ALIGNMENT__} True
                        {$else} False {$endif};
     
     { Convert single variables from or to little or big endian format.
       This only works for a single variable or a plain array of a simple
       type. For more complicated structures, this has to be done for
       each component separately! Currently, ConvertFromFooEndian and
       ConvertToFooEndian are the same, but this might not be the case on
       middle-endian machines. Therefore, we provide different names. }
     procedure ReverseBytes            (var Buf; ElementSize, Count :
       SizeType); asmname '_p_reversebytes';
     procedure ConvertFromLittleEndian (var Buf; ElementSize, Count :
       SizeType); asmname '_p_convertlittleendian';
     procedure ConvertFromBigEndian    (var Buf; ElementSize, Count :
       SizeType); asmname '_p_convertbigendian';
     procedure ConvertToLittleEndian   (var Buf; ElementSize, Count :
       SizeType); asmname '_p_convertlittleendian';
     procedure ConvertToBigEndian      (var Buf; ElementSize, Count :
       SizeType); asmname '_p_convertbigendian';
     
     { Read a block from a file and convert it from little or
       big endian format. This only works for a single variable or a
       plain array of a simple type, note the comment for
       `ConvertFromLittleEndian' and `ConvertFromBigEndian'. }
     (*@@iocritical*)procedure BlockReadLittleEndian   (var aFile : File;
       var   Buf; ElementSize, Count : SizeType);
       asmname '_p_blockread_littleendian';
     (*@@iocritical*)procedure BlockReadBigEndian      (var aFile : File;
       var   Buf; ElementSize, Count : SizeType);
       asmname '_p_blockread_bigendian';
     
     { Write a block variable to a file and convert it to little or big
       endian format before. This only works for a single variable or a
       plain array of a simple type. Apart from this, note the comment
       for `ConvertToLittleEndian' and `ConvertToBigEndian'. }
     (*@@iocritical*)procedure BlockWriteLittleEndian  (var aFile : File;
       const Buf; ElementSize, Count : SizeType);
       asmname '_p_blockwrite_littleendian';
     (*@@iocritical*)procedure BlockWriteBigEndian     (var aFile : File;
       const Buf; ElementSize, Count : SizeType);
       asmname '_p_blockwrite_bigendian';
     
     { Read and write strings from/to binary files, where the length is
       stored in the given endianness and with a fixed size (64 bits),
       and therefore is independent of the system. }
     (*@@iocritical*)procedure ReadStringLittleEndian  (var f : File; var
       s : String); asmname '_p_ReadStringLittleEndian';
     (*@@iocritical*)procedure ReadStringBigEndian     (var f : File; var
       s : String); asmname '_p_ReadStringBigEndian';
     (*@@iocritical*)procedure WriteStringLittleEndian (var f : File;
       const s : String); asmname '_p_WriteStringLittleEndian';
     (*@@iocritical*)procedure WriteStringBigEndian    (var f : File;
       const s : String); asmname '_p_WriteStringBigEndian';
     
     { =================== STRING HANDLING ROUTINES =================== }
     
     { String handling routines, from string.pas }
     
     type
       AnyFile = Text; (*@@ create `AnyFile' parameters*)
       PAnyFile = ^AnyFile;
     
     { TString is a string type that is used for function results and
       local variables, as long as undiscriminated strings are not
       allowed there. The default size of 2048 characters should be
       enough for file names on any system, but can be changed when
       necessary. It should be at least as big as MAXPATHLEN. }
     
     const
       TStringSize = 2048;
       SpaceCharacters = [' ', #9];
       NewLine = "\n"; { the separator of lines within a string }
       LineBreak = {$ifdef __OS_DOS__} "\r\n" {$else} "\n" {$endif};
       { the separator of lines within a file }
     
     type
       TString    = String (TStringSize);
       TStringBuf = packed array [0 .. TStringSize] of Char;
       PString    = ^String;
       CharSet    = set of Char;
       PCStrings  = ^TCStrings;
       TCStrings  = array [0 .. MaxVarSize div SizeOf (CString)] of
       CString;
     
     var
       CParamCount : Integer; asmname '_p_argc'; external;
       CParameters : PCStrings; asmname '_p_argv'; external;
     
     function  MemCmp      (const s1, s2; Size : SizeType) : Integer;
       asmname 'memcmp';
     function  MemComp     (const s1, s2; Size : SizeType) : Integer;
       asmname 'memcmp';
     function  MemCompCase (const s1, s2; Size : SizeType) : Boolean;
       asmname '_p_memcmpcase';
     
     procedure UpCaseString    (var s : String);
       asmname '_p_upcase_string';
     procedure LoCaseString    (var s : String);
       asmname '_p_locase_string';
     function  UpCaseStr       (const s : String) : TString;
       asmname '_p_upcase_str';
     function  LoCaseStr       (const s : String) : TString;
       asmname '_p_locase_str';
     
     function  IsUpCase        (ch : Char) : Boolean;
       attribute (const); asmname '_p_isupcase';
     function  IsLoCase        (ch : Char) : Boolean;
       attribute (const); asmname '_p_islocase';
     function  IsAlphaNum      (ch : Char) : Boolean;
       attribute (const); asmname '_p_isalphanum';
     function  IsAlphaNumUnderscore (ch : Char) : Boolean;
       attribute (const); asmname '_p_isalphanumunderscore';
     function  IsPrintable     (ch : Char) : Boolean;
       attribute (const); asmname '_p_isprintable';
     
     function  StrEqualCase    (const s1, s2 : String) : Boolean;
       asmname '_p_strequalcase';
     
     function  Pos             (const SubString, aString : String) :
       Integer; asmname '_p_pos';
     function  LastPos         (const SubString, aString : String) :
       Integer; asmname '_p_lastpos';
     function  PosCase         (const SubString, aString : String) :
       Integer; asmname '_p_poscase';
     function  LastPosCase     (const SubString, aString : String) :
       Integer; asmname '_p_lastposcase';
     function  CharPos         (const Chars : CharSet; const aString :
       String) : Integer; asmname '_p_charpos';
     function  LastCharPos     (const Chars : CharSet; const aString :
       String) : Integer; asmname '_p_lastcharpos';
     
     function  PosFrom         (const SubString, aString : String; From :
       Integer) : Integer; asmname '_p_posfrom';
     function  LastPosTill     (const SubString, aString : String; Till :
       Integer) : Integer; asmname '_p_lastpostill';
     function  PosFromCase     (const SubString, aString : String; From :
       Integer) : Integer; asmname '_p_posfromcase';
     function  LastPosTillCase (const SubString, aString : String; Till :
       Integer) : Integer; asmname '_p_lastpostillcase';
     function  CharPosFrom     (const Chars : CharSet; const aString :
       String; From : Integer) : Integer; asmname '_p_charposfrom';
     function  LastCharPosTill (const Chars : CharSet; const aString :
       String; Till : Integer) : Integer; asmname '_p_lastcharpostill';
     
     function  IsPrefix        (const Prefix, s : String) : Boolean;
       asmname '_p_isprefix';
     function  IsSuffix        (const Suffix, s : String) : Boolean;
       asmname '_p_issuffix';
     function  IsPrefixCase    (const Prefix, s : String) : Boolean;
       asmname '_p_isprefixcase';
     function  IsSuffixCase    (const Suffix, s : String) : Boolean;
       asmname '_p_issuffixcase';
     
     function  CStringLength      (Src : CString) : SizeType;
       asmname '_p_strlen';
     function  CStringEnd         (Src : CString) : CString;
       asmname '_p_strend';
     function  CStringNew         (Src : CString) : CString;
       asmname '_p_strdup';
     function  CStringComp        (s1, s2 : CString) : Integer;
       asmname '_p_strcmp';
     function  CStringCaseComp    (s1, s2 : CString) : Integer;
       asmname '_p_strcasecmp';
     function  CStringLComp       (s1, s2 : CString; MaxLen : SizeType) :
       Integer; asmname '_p_strlcmp';
     function  CStringLCaseComp   (s1, s2 : CString; MaxLen : SizeType) :
       Integer; asmname '_p_strlcasecmp';
     function  CStringCopy        (Dest, Source : CString) : CString;
       asmname '_p_strcpy';
     function  CStringCopyEnd     (Dest, Source : CString) : CString;
       asmname '_p_strecpy';
     function  CStringLCopy       (Dest, Source : CString; MaxLen :
       SizeType) : CString; asmname '_p_strlcpy';
     function  CStringMove        (Dest, Source : CString; Count :
       SizeType) : CString; asmname '_p_strmove';
     function  CStringCat         (Dest, Source : CString) : CString;
       asmname '_p_strcat';
     function  CStringLCat        (Dest, Source : CString; MaxLen :
       SizeType) : CString; asmname '_p_strlcat';
     function  CStringChPos       (Src : CString; Ch : Char) : CString;
       asmname '_p_strscan';
     function  CStringLastChPos   (Src : CString; Ch : Char) : CString;
       asmname '_p_strrscan';
     function  CStringPos         (aString, SubString : CString) :
       CString; asmname '_p_strpos';
     function  CStringLastPos     (aString, SubString : CString) :
       CString; asmname '_p_strrpos';
     function  CStringCasePos     (aString, SubString : CString) :
       CString; asmname '_p_strcasepos';
     function  CStringLastCasePos (aString, SubString : CString) :
       CString; asmname '_p_strrcasepos';
     function  CStringUpCase      (s : CString) : CString;
       asmname '_p_strupper';
     function  CStringLoCase      (s : CString) : CString;
       asmname '_p_strlower';
     function  CStringIsEmpty     (s : CString) : Boolean;
       asmname '_p_strempty';
     function  NewCString         (const Source : String) : CString;
       asmname '_p_newcstring';
     function  CStringCopyString  (Dest : CString; const Source :
       String) : CString; asmname '_p_cstringcopystring';
     procedure CopyCString        (Source : CString; var Dest : String);
       asmname '_p_copycstring';
     
     function  NewString       (const s : String) : PString;
       asmname '_p_newstring';
     procedure DisposeString   (p : PString); asmname '_p_dispose';
     
     procedure SetString       (var s : String; Buffer : PChar; Count :
       Integer); asmname '_p_set_string';
     function  StringOfChar    (Ch : Char; Count : Integer) = s :
       TString; asmname '_p_string_of_char';
     
     procedure TrimLeft        (var s : String); asmname '_p_trimleft';
     procedure TrimRight       (var s : String); asmname '_p_trimright';
     procedure TrimBoth        (var s : String); asmname '_p_trimboth';
     function  TrimLeftStr     (const s : String) : TString;
       asmname '_p_trimleft_str';
     function  TrimRightStr    (const s : String) : TString;
       asmname '_p_trimright_str';
     function  TrimBothStr     (const s : String) : TString;
       asmname '_p_trimboth_str';
     
     function  GetStringCapacity (const s : String) : Integer;
       asmname '_p_get_string_capacity';
     
     { A shortcut for a common use of WriteStr as a function }
     function  Integer2String (i : Integer) : TString;
       asmname '_p_Integer2String';
     
     type
       TChars = packed array [1 .. 1] of Char;
       PChars = ^TChars;
     
       { Under development. Interface subject to change.
         Use with caution. }
       { When a const or var AnyString parameter is passed, internally
         these records are passed as const parameters. Value AnyString
         parameters are passed like value string parameters. }
       ConstAnyString = record
         Length : Integer;
         Chars  : PChars
       end;
     
       { Capacity is the allocated space (used internally). Count is the
         actual number of environment strings. The CStrings array
         contains the environment strings, terminated by a nil pointer,
         which is not counted in Count. @CStrings can be passed to libc
         routines like execve which expect an environment (see
         GetCEnvironment). }
       PEnvironment = ^TEnvironment;
       TEnvironment (Capacity : Integer) = record
         Count : Integer;
         CStrings : array [1 .. Capacity + 1] of CString
       end;
     
     var
       Environment : PEnvironment; asmname '_p_environment'; external;
     
     { Get an environment variable. If it does not exist, GetEnv returns
       the empty string, which can't be distinguished from a variable
       with an empty value, while CStringGetEnv returns nil then. Note,
       Dos doesn't know empty environment variables, but treats them as
       non-existing, and does not distinguish case in the names of
       environment variables. However, even under Dos, empty environment
       variables and variable names with different case can now be set
       and used within GPC programs. }
     function  GetEnv (const EnvVar : String) : TString;
       asmname '_p_getenv';
     function  CStringGetEnv (EnvVar : CString) : CString;
       asmname '_p_cstringgetenv';
     
     { Sets an environment variable with the name given in VarName to the
       value
       Value. A previous value, if any, is overwritten. }
     procedure SetEnv (const VarName, Value : String);
       asmname '_p_setenv';
     
     { Un-sets an environment variable with the name given in VarName. }
     procedure UnSetEnv (const VarName : String); asmname '_p_unsetenv';
     
     { Returns @Environment^.CStrings, converted to PCStrings, to be
       passed to
       libc routines like execve which expect an environment. }
     function  GetCEnvironment : PCStrings; asmname '_p_getcenvironment';
     
     { ================= RUNTIME ERROR HANDLING ETC. ================== }
     
     { Error handling functions, from error.pas }
     
     const
       EOpen = 405;
       EOpenRead = 442;
       EOpenWrite = 443;
       EOpenUpdate = 444;
       EReading = 464;
       EWriting = 466;
       ERead = 413;
       EWrite = 414;
       EWriteReadOnly = 422;
       EMMap = 408;
       EIOCtl = 630;
       EConvertError = 875;
     
     var
       { Error number (after runtime error) or exit status (after Halt)
       or
         0 (during program run and after succesful termination). }
       ExitCode : Integer; asmname '_p_exitcode'; external;
     
       { Contains the address of the code where a runtime occurred, nil
         if no runtime error occurred. }
       ErrorAddr : Pointer; asmname '_p_erroraddr'; external;
     
       { Error message }
       ErrorMessageString : TString; asmname '_p_errormessagestring';
       external;
     
     function  GetErrorMessage                 (n : Integer) : CString;
       asmname '_p_errmsg';
     procedure RuntimeError                    (n : Integer);
       attribute (noreturn); asmname '_p_error';
     procedure RuntimeErrorInteger             (n : Integer; i : MedInt);
       attribute (noreturn); asmname '_p_error_integer';
     procedure RuntimeErrorCString             (n : Integer; s :
       CString);                attribute (noreturn);
       asmname '_p_error_string';
     procedure InternalError                   (n : Integer);
       attribute (noreturn); asmname '_p_internal_error';
     procedure InternalErrorInteger            (n : Integer; i : MedInt);
       attribute (noreturn); asmname '_p_internal_error_integer';
     procedure RuntimeWarning                  (Message : CString);
       asmname '_p_warning';
     procedure RuntimeWarningInteger           (Message : CString; i :
       MedInt); asmname '_p_warning_integer';
     procedure RuntimeWarningCString           (Message : CString; s :
       CString); asmname '_p_warning_string';
     procedure DebugStatement                  (const FileName : String;
       Line : Integer); asmname '_p_debug_statement';
     
     (*iocritical*)procedure IOError                         (n :
       Integer); asmname '_p_io_error';
     (*iocritical*)procedure IOErrorInteger                  (n :
       Integer; i : MedInt); asmname '_p_io_error_integer';
     (*iocritical*)procedure IOErrorCString                  (n :
       Integer; s : CString); asmname '_p_io_error_string';
     (*iocritical*)procedure IOErrorFile                     (n :
       Integer; protected var f : AnyFile); asmname '_p_io_error_file';
     function  GetIOErrorMessage : TString;
       asmname '_p_get_io_error_message';
     procedure CheckInOutRes; asmname '_p_check_inoutres';
     
     { Registers a procedure to be called to restore the terminal for
       another process that accesses the terminal, or back for the
       program itself. Used e.g. by the CRT unit. The procedures must
       allow for being called multiple times in any order, even at the
       end of the program (see the comment for RestoreTerminal). }
     procedure RegisterRestoreTerminal (ForAnotherProcess : Boolean;
       procedure Proc); asmname '_p_RegisterRestoreTerminal';
     
     { Unregisters a procedure registered with RegisterRestoreTerminal.
       Returns False if the procedure had not been registered, and True
       if it had been registered and was unregistered successfully. }
     function UnregisterRestoreTerminal (ForAnotherProcess : Boolean;
       procedure Proc) : Boolean; asmname '_p_UnregisterRestoreTerminal';
     
     { Calls the procedures registered by RegisterRestoreTerminal. When
       restoring the terminal for another process, the procedures are
       called in the opposite order of registration. When restoring back
       for the program, they are called in the order of registration.
     
       `RestoreTerminal (True)' will also be called at the end of the
       program, before outputting any runtime error message. It can also
       be used if you want to write an error message and exit the program
       (especially when using e.g. the CRT unit). For this purpose, to
       avoid side effects, call RestoreTerminal immediately before
       writing the error message (to StdErr, not to Output!), and then
       exit the program (e.g. with Halt). }
     procedure RestoreTerminal (ForAnotherProcess : Boolean);
       asmname '_p_RestoreTerminal';
     
     { Executes a command line. Reports execution errors via the IOResult
       mechanism and returns the exit status of the executed program.
       Execute calls RestoreTerminal with the argument True before and
       False after executing the process, ExecuteNoTerminal does not. }
     (*@@IO critical*)function  Execute (const CmdLine : String) :
       Integer; asmname '_p_execute';
     (*@@IO critical*)function  ExecuteNoTerminal (const CmdLine :
       String) : Integer; asmname '_p_executenoterminal';
     
     procedure AtExit (procedure Proc); asmname '_p_atexit';
     
     procedure SetReturnAddress (Address : Pointer);
       asmname '_p_SetReturnAddress';
     procedure RestoreReturnAddress; asmname '_p_RestoreReturnAddress';
     
     { ==================== SIGNALS AND PROCESSES ===================== }
     
     function  ProcessID : Integer; asmname '_p_pid';
     
     { Extract information from the status returned by PWait }
     function StatusExited     (Status : Integer) : Boolean; attribute
       (const); asmname '_p_WIfExited';
     function StatusExitCode   (Status : Integer) : Integer; attribute
       (const); asmname '_p_WExitStatus';
     function StatusSignaled   (Status : Integer) : Boolean; attribute
       (const); asmname '_p_WIfSignaled';
     function StatusTermSignal (Status : Integer) : Integer; attribute
       (const); asmname '_p_WTermSig';
     function StatusStopped    (Status : Integer) : Boolean; attribute
       (const); asmname '_p_WIfStopped';
     function StatusStopSignal (Status : Integer) : Integer; attribute
       (const); asmname '_p_WStopSig';
     
     type
       TSignalHandler = procedure (Signal : Integer);
     
     { OldHandler and OldRestart may be null }
     function InstallSignalHandler (Signal : Integer; Handler :
       TSignalHandler;
                                    Restart, UnlessIgnored : Boolean;
                                    var OldHandler : TSignalHandler; var
       OldRestart : Boolean) : Boolean; asmname '_p_sigaction';
     procedure BlockSignal   (Signal : Integer; Block : Boolean);
       asmname '_p_BlockSignal';
     function  SignalBlocked (Signal : Integer) : Boolean;
       asmname '_p_SignalBlocked';
     
     var
       { Signal actions }
       SignalDefault : TSignalHandler; asmname '_p_SIG_DFL'; external;
       SignalIgnore  : TSignalHandler; asmname '_p_SIG_IGN'; external;
       SignalError   : TSignalHandler; asmname '_p_SIG_ERR'; external;
     
       { Signals. The constants are set to the signal numbers, and
         are 0 for signals not defined. }
       { POSIX signals }
       SigHUp    : Integer; asmname '_p_SIGHUP'; external;
       SigInt    : Integer; asmname '_p_SIGINT'; external;
       SigQuit   : Integer; asmname '_p_SIGQUIT'; external;
       SigIll    : Integer; asmname '_p_SIGILL'; external;
       SigAbrt   : Integer; asmname '_p_SIGABRT'; external;
       SigFPE    : Integer; asmname '_p_SIGFPE'; external;
       SigKill   : Integer; asmname '_p_SIGKILL'; external;
       SigSegV   : Integer; asmname '_p_SIGSEGV'; external;
       SigPipe   : Integer; asmname '_p_SIGPIPE'; external;
       SigAlrm   : Integer; asmname '_p_SIGALRM'; external;
       SigTerm   : Integer; asmname '_p_SIGTERM'; external;
       SigUsr1   : Integer; asmname '_p_SIGUSR1'; external;
       SigUsr2   : Integer; asmname '_p_SIGUSR2'; external;
       SigChld   : Integer; asmname '_p_SIGCHLD'; external;
       SigCont   : Integer; asmname '_p_SIGCONT'; external;
       SigStop   : Integer; asmname '_p_SIGSTOP'; external;
       SigTStp   : Integer; asmname '_p_SIGTSTP'; external;
       SigTTIn   : Integer; asmname '_p_SIGTTIN'; external;
       SigTTOu   : Integer; asmname '_p_SIGTTOU'; external;
     
       { Non-POSIX signals }
       SigTrap   : Integer; asmname '_p_SIGTRAP'; external;
       SigIOT    : Integer; asmname '_p_SIGIOT'; external;
       SigEMT    : Integer; asmname '_p_SIGEMT'; external;
       SigBus    : Integer; asmname '_p_SIGBUS'; external;
       SigSys    : Integer; asmname '_p_SIGSYS'; external;
       SigStkFlt : Integer; asmname '_p_SIGSTKFLT'; external;
       SigUrg    : Integer; asmname '_p_SIGURG'; external;
       SigIO     : Integer; asmname '_p_SIGIO'; external;
       SigPoll   : Integer; asmname '_p_SIGPOLL'; external;
       SigXCPU   : Integer; asmname '_p_SIGXCPU'; external;
       SigXFSz   : Integer; asmname '_p_SIGXFSZ'; external;
       SigVTAlrm : Integer; asmname '_p_SIGVTALRM'; external;
       SigProf   : Integer; asmname '_p_SIGPROF'; external;
       SigPwr    : Integer; asmname '_p_SIGPWR'; external;
       SigInfo   : Integer; asmname '_p_SIGINFO'; external;
       SigLost   : Integer; asmname '_p_SIGLOST'; external;
       SigWinCh  : Integer; asmname '_p_SIGWINCH'; external;
     
       { Signal subcodes (only used on some systems, -1 if not used) }
       FPEIntegerOverflow        : Integer; asmname '_p_FPE_INTOVF_TRAP';
       external;
       FPEIntegerDivisionByZero  : Integer; asmname '_p_FPE_INTDIV_TRAP';
       external;
       FPESubscriptRange         : Integer; asmname '_p_FPE_SUBRNG_TRAP';
       external;
       FPERealOverflow           : Integer; asmname '_p_FPE_FLTOVF_TRAP';
       external;
       FPERealDivisionByZero     : Integer; asmname '_p_FPE_FLTDIV_TRAP';
       external;
       FPERealUnderflow          : Integer; asmname '_p_FPE_FLTUND_TRAP';
       external;
       FPEDecimalOverflow        : Integer; asmname '_p_FPE_DECOVF_TRAP';
       external;
     
     { Returns a description for a signal }
     function  StrSignal (Signal : Integer) : TString;
       asmname '_p_strsignal';
     
     { Sends a signal to a process. Returns True if successful. If Signal
       is 0, it doesn't send a signal, but still checks whether it would
       be possible to send a signal to the given process. }
     function  Kill (PID, Signal : Integer) : Boolean; asmname '_p_kill';
     
     const
       AnyChild = - 1;
     
     { Waits for a child process with the given PID (or any child process
       if PID = AnyChild) to terminate or be stopped. Returns the PID of
       the process. WStatus will contain the status and can be evaluated
       with StatusExited etc.. If nothing happened, and Block is False,
       the function will return 0, and WStatus will be 0. If an error
       occurred (especially on single tasking systems where WaitPID is
       not possible), the function will return a negative value, and
       WStatus will be 0. }
     function  WaitPID (PID : Integer; var WStatus : Integer; Block :
       Boolean) : Integer; asmname '_p_waitpid';
     
     { Sets the process group of Process (or the current one if Process
       is 0) to ProcessGroup (or its PID if ProcessGroup is 0). Returns
       True if successful. }
     function  SetProcessGroup (Process, ProcessGroup : Integer) :
       Boolean; asmname '_p_setpgid';
     
     { Sets the process group of a terminal given by Terminal (as a file
       handle) to ProcessGroup. ProcessGroup must be the ID of a process
       group in the same session. Returns True if successful. }
     function  SetTerminalProcessGroup (Terminal, ProcessGroup :
       Integer) : Boolean; asmname '_p_tcsetpgrp';
     
     { Returns the process group of a terminal given by Terminal (as a
       file handle), or -1 on error. }
     function  GetTerminalProcessGroup (Terminal : Integer) : Integer;
       asmname '_p_tcgetpgrp';
     
     { Returns the file name of the terminal device that is open on the
       file f. Returns nil if (and only if) f is not open or not
       connected to a terminal. }
     function  GetTerminalName (protected var f : AnyFile) : CString;
       asmname '_p_ttyname';
     
     { Set the standard input's signal generation, if it is a terminal. }
     procedure SetInputSignals (Signals : Boolean);
       asmname '_p_set_isig';
     
     { Get the standard input's signal generation, if it is a terminal. }
     function  GetInputSignals : Boolean; asmname '_p_get_isig';
     
     { Returns the real or effective user ID of the process. }
     function  UserID  (Effective : Boolean) : Integer; asmname '_p_uid';
     
     { Returns the real or effective group ID of the process. }
     function  GroupID (Effective : Boolean) : Integer; asmname '_p_gid';
     
     { ================= COMMAND LINE OPTION PARSING ================== }
     
     const
       EndOfOptions      = #255;
       NoOption          = #1;
       UnknownOption     = '?';
       LongOption        = #0;
       UnknownLongOption = '?';
     
     var
       FirstNonOption         : Integer; asmname '_p_first_non_option';
       external;
       HasOptionArgument      : Boolean;
       asmname '_p_has_option_argument';      external;
       OptionArgument         : TString; asmname '_p_option_argument';
       external;
       UnknownOptionCharacter : Char;
       asmname '_p_unknown_option_character'; external;
       GetOptErrorFlag        : Boolean; asmname '_p_getopt_error_flag';
       external;
     
     {
       Parses command line arguments for options and returns the next
       one.
     
       If a command line argument starts with `-', and is not exactly `-'
       or `--', then it is an option element. The characters of this
       element (aside from the initial `-') are option characters. If
       `GetOpt' is called repeatedly, it returns successively each of the
       option characters from each of the option elements.
     
       If `GetOpt' finds another option character, it returns that
       character, updating `FirstNonOption' and internal variables so
       that the next call to `GetOpt' can resume the scan with the
       following option character or command line argument.
     
       If there are no more option characters, `GetOpt' returns
       EndOfOptions. Then `FirstNonOption' is the index of the first
       command line argument that is not an option. (The command line
       arguments have been permuted so that those that are not options
       now come last.)
     
       OptString must be of the form `[+|-]abcd:e:f:g::h::i::'.
     
       a, b, c are options without arguments
       d, e, f are options with required arguments
       g, h, i are options with optional arguments
     
       Arguments are text following the option character in the same
       command line argument, or the text of the following command line
       argument. They are returned in OptionArgument. If an option has no
       argument, OptionArgument is empty. The variable HasOptionArgument
       tells whether an option has an argument. This is mostly useful for
       options with optional arguments, if one wants to distinguish an
       empty argument from no argument.
     
       If the first character of OptString is `+', GetOpt stops at the
       first non-option argument.
     
       If it is `-', GetOpt treats non-option arguments as options and
       return NoOption for them.
     
       Otherwise, GetOpt permutes arguments and handles all options,
       leaving all non-options at the end. However, if the environment
       variable POSIXLY_CORRECT is set, the default behaviour is to stop
       at the first non-option argument, as with `+'.
     
       The special argument `--' forces an end of option-scanning
       regardless of the first character of OptString. In the case of
       `-', only `--' can cause GetOpt to return EndOfOptions with
       FirstNonOption <= ParamCount.
     
       If an option character is seen that is not listed in OptString,
       UnknownOption is returned. The unrecognized option character is
       stored in UnknownOptionCharacter. Unless GetOptErrorFlag is set to
       False, an error message is printed to StdErr automatically.
     }
     function GetOpt (const OptString : String) : Char;
       asmname '_p_getopt';
     
     type
       OptArgType = (NoArgument, RequiredArgument, OptionalArgument);
     
       OptionType = record
         Name     : CString;
         Argument : OptArgType;
         Flag     : ^Char; { if nil, V is returned. Otherwise, Flag^ is }
         V        : Char   { set to V, and LongOption is returned }
       end;
     
     {
       Recognize short options, described by OptString as above, and long
       options, described by LongOptions.
     
       Long-named options begin with `--' instead of `-'. Their names may
       be abbreviated as long as the abbreviation is unique or is an
       exact match for some defined option. If they have an argument, it
       follows the option name in the same argument, separated from the
       option name by a `=', or else the in next argument. When GetOpt
       finds a long-named option, it returns LongOption if that option's
       `Flag' field is non-nil, and the value of the option's `V' field
       if the `Flag' field is nil.
     
       LongIndex, if not null, returns the index in LongOptions of the
       long-named option found. It is only valid when a long-named option
       has been found by the most recent call.
     
       If LongOnly is set, `-' as well as `--' can indicate a long
       option. If an option that starts with `-' (not `--') doesn't match
       a long option, but does match a short option, it is parsed as a
       short option instead. If an argument has the form `-f', where f is
       a valid short option, don't consider it an abbreviated form of a
       long option that starts with `f'. Otherwise there would be no way
       to give the `-f' short option. On the other hand, if there's a
       long option `fubar' and the argument is `-fu', do consider that an
       abbreviation of the long option, just like `--fu', and not `-f'
       with argument `u'. This distinction seems to be the most useful
       approach.
     
       As an additional feature (not present in the C counterpart), if
       the last character of OptString is `-' (after a possible starting
       `+' or `-' character), or OptString is empty, all long options
       with a nil `Flag' field will automatically be recognized as short
       options with the character given by the `V' field. This means, in
       the common (and recommended) case that all short options have long
       equivalents, you can simply pass an empty OptString (or pass `+-'
       or `--' as OptString if you want this behaviour, see the comment
       for GetOpt), and you will only have to maintain the LongOptions
       array when you add or change options.
     }
     function GetOptLong (const OptString : String; var LongOptions :
       array [m .. n : Integer] of OptionType { can be null };
                          var LongIndex : Integer { can be null };
       LongOnly : Boolean) : Char; asmname '_p_getopt_long';
     
     { Reset GetOpt's state and make the next GetOpt or GetOptLong start
       (again) with the StartArgument'th argument (may be 1). This is
       useful for special purposes only. It is *necessary* to do this
       after altering the contents of CParamCount/CParameters (which is
       not usually done, either). }
     procedure ResetGetOpt (StartArgument : Integer);
       asmname '_p_ResetGetOpt';
     
     { =========================== PEXECUTE =========================== }
     
     const
       PExecute_First   = 1;
       PExecute_Last    = 2;
       PExecute_One     = PExecute_First or PExecute_Last;
       PExecute_Search  = 4;
       PExecute_Verbose = 8;
     
     {
       PExecute: execute a program.
     
       Program and Arguments are the arguments to execv/execvp.
     
       Flags and PExecute_Search is non-zero if $PATH should be searched
       (It's not clear that GCC passes this flag correctly). Flags and
       PExecute_First is nonzero for the first process in chain. Flags
       and PExecute_Last is nonzero for the last process in chain.
     
       The result is the pid on systems like Unix where we fork/exec and
       on systems like MS-Windows and OS2 where we use spawn. It is up to
       the caller to wait for the child.
     
       The result is the exit code on systems like MSDOS where we spawn
       and wait for the child here.
     
       Upon failure, ErrMsg is set to the text of the error message,
       and -1 is returned. `errno' is available to the caller to use.
     
       PWait: cover function for wait.
     
       PID is the process id of the task to wait for. Status is the
       `status' argument to wait. Flags is currently unused (allows
       future enhancement without breaking upward compatibility). Pass 0
       for now.
     
       The result is the process ID of the child reaped, or -1 for
       failure.
     
       On systems that don't support waiting for a particular child, PID
       is ignored. On systems like MSDOS that don't really multitask
       PWait is just a mechanism to provide a consistent interface for
       the caller.
     }
     function PExecute (ProgramName : CString; Arguments : PCStrings; var
       ErrMsg : String; Flags : Integer) : Integer;
       asmname '_p_pexecute';
     function PWait (PID : Integer; var Status : Integer; Flags :
       Integer) : Integer; asmname 'pwait';
     
     { ==================== TIME HANDLING ROUTINES ==================== }
     
     { Time and date routines for Extended Pascal, from time.pas }
     
     const
       DateLength = 11; { from types.h }
       TimeLength = 8;  { from types.h }
       InvalidYear = - MaxInt;
     
     type
       UnixTimeType = LongInt; { This is hard-coded in the compiler. Do
       not change here. }
       MicroSecondTimeType = LongInt;
     
       DateString = packed array [1 .. DateLength] of Char;
       TimeString = packed array [1 .. TimeLength] of Char;
     
     var
       { DayOfWeekName is a constant and therefore does not respect the
         locale. Therefore, it's recommended to use FormatTime instead. }
       DayOfWeekName : array [0 .. 6] of String [9];
       asmname '_p_downame'; external;
     
       { MonthName is a constant and therefore does not respect the
         locale. Therefore, it's recommended to use FormatTime instead. }
       MonthName : array [1 .. 12] of String [9]; asmname '_p_monthname';
       external;
     
     function  GetDayOfWeek (Day, Month, Year : Integer) : Integer;
       asmname '_p_dayofweek';
     procedure UnixTimeToTimeStamp (UnixTime : UnixTimeType; var
       aTimeStamp : TimeStamp); asmname '_p_unix_time_to_time_stamp';
     function  TimeStampToUnixTime (protected var aTimeStamp :
       TimeStamp) : UnixTimeType; asmname '_p_time_stamp_to_unix_time';
     function  GetMicroSecondTime : MicroSecondTimeType;
       asmname '_p_get_micro_second_time';
     
     { Is the year a leap year? }
     function  IsLeapYear (Year : Integer) : Boolean;
       asmname '_p_is_leap_year';
     
     { Returns the length of the month, taking leap years into account. }
     function  MonthLength (Month, Year : Integer) : Integer;
       asmname '_p_month_length';
     
     procedure Sleep (Seconds : Integer); asmname '_p_sleep';
     procedure SleepMicroSeconds (MicroSeconds : Integer);
       asmname '_p_sleep_microseconds';
     function  Alarm (Seconds : Integer) : Integer; asmname '_p_alarm';
     procedure UnixTimeToTime (UnixTime : UnixTimeType; var Year, Month,
       Day, Hour, Minute, Second : Integer);
       asmname '_p_unix_time_to_time';
     function  TimeToUnixTime (Year, Month, Day, Hour, Minute, Second :
       Integer) : UnixTimeType; asmname '_p_time_to_unix_time';
     
     { Get the real time. MicroSecond can be null and is ignored then. }
     function  GetUnixTime (var MicroSecond : Integer) : UnixTimeType;
       asmname '_p_get_unix_time';
     
     { Get the CPU time used. MicroSecond can be null and is ignored
       then.
       Now, GetCPUTime can measure long CPU times reliably on most
       systems
       (e.g. Solaris where it didn't work before). }
     function  GetCPUTime (var MicroSecond : Integer) : Integer;
       asmname '_p_get_cpu_time';
     
     {
       Formats a TimeStamp value according to a Format string. The format
       string can contain date/time items consisting of `%', followed by
       the specifiers listed below. All characters outside of these items
       are copied to the result unmodified. The specifiers correspond to
       those of the C function strftime(), including POSIX.2 and glibc
       extensions and some more extensions. The extensions are also
       available on systems whose strftime() doesn't support them.
     
       The following modifiers may appear after the `%':
     
       `_'  The item is left padded with spaces to the given or default
            width.
     
       `-'  The item is not padded at all.
     
       `0'  The item is left padded with zeros to the given or default
            width.
     
       `/'  The item is right trimmed if it is longer than the given
            width.
     
       `^'  The item is converted to upper case.
     
       `~'  The item is converted to lower case.
     
       After zero or more of these flags, an optional width may be
       specified for padding and trimming. It must be given as a decimal
       number (not starting with `0' since `0' has a meaning of its own,
       see above).
     
       Afterwards, the following optional modifiers may follow. Their
       meaning is locale-dependent, and many systems and locales just
       ignore them.
     
       `E'  Use the locale's alternate representation for date and time.
            In a Japanese locale, for example, `%Ex' might yield a date
            format based on the Japanese Emperors' reigns.
     
       `O'  Use the locale's alternate numeric symbols for numbers. This
            modifier applies only to numeric format specifiers.
     
       Finally, exactly one of the following specifiers must appear. The
       padding rules listed here are the defaults that can be overriden
       with the modifiers listed above.
     
       `a'  The abbreviated weekday name according to the current locale.
     
       `A'  The full weekday name according to the current locale.
     
       `b'  The abbreviated month name according to the current locale.
     
       `B'  The full month name according to the current locale.
     
       `c'  The preferred date and time representation for the current
            locale.
     
       `C'  The century of the year. This is equivalent to the greatest
            integer not greater than the year divided by 100.
     
       `d'  The day of the month as a decimal number (`01' .. `31').
     
       `D'  The date using the format `%m/%d/%y'. NOTE: Don't use this
            format if it can be avoided. Things like this caused Y2K
            bugs!
     
       `e'  The day of the month like with `%d', but padded with blanks
            (` 1' .. `31').
     
       `F'  The date using the format `%Y-%m-%d'. This is the form
            specified in the ISO 8601 standard and is the preferred form
            for all uses.
     
       `g'  The year corresponding to the ISO week number, but without
            the century (`00' .. `99'). This has the same format and
            value as `y', except that if the ISO week number (see `V')
            belongs to the previous or next year, that year is used
            instead. NOTE: Don't use this format if it can be avoided.
            Things like this caused Y2K bugs!
     
       `G'  The year corresponding to the ISO week number. This has the
            same format and value as `Y', except that if the ISO week
            number (see `V') belongs to the previous or next year, that
            year is used instead.
     
       `h'  The abbreviated month name according to the current locale.
            This is the same as `b'.
     
       `H'  The hour as a decimal number, using a 24-hour clock
            (`00' .. `23').
     
       `I'  The hour as a decimal number, using a 12-hour clock
            (`01' .. `12').
     
       `j'  The day of the year as a decimal number (`001' .. `366').
     
       `k'  The hour as a decimal number, using a 24-hour clock like `H',
            but padded with blanks (` 0' .. `23').
     
       `l'  The hour as a decimal number, using a 12-hour clock like `I',
            but padded with blanks (` 1' .. `12').
     
       `m'  The month as a decimal number (`01' .. `12').
     
       `M'  The minute as a decimal number (`00' .. `59').
     
       `n'  A single newline character.
     
       `p'  Either `AM' or `PM', according to the given time value; or
            the corresponding strings for the current locale. Noon is
            treated as `PM' and midnight as `AM'.
     
       `P'  Either `am' or `pm', according to the given time value; or
            the corresponding strings for the current locale, printed in
            lowercase characters. Noon is treated as `pm' and midnight as
            `am'.
     
       `Q'  The fractional part of the second. This format has special
            effects on the modifiers. The width, if given, determines the
            number of digits to output. Therefore, no actual clipping or
            trimming is done. However, if padding with spaces is
            specified, any trailing (i.e., left!) zeros are converted to
            spaces, and if "no padding" is specified, they are removed.
            The default is "padding with zeros", i.e. trailing zeros are
            left unchanged. The digits are cut when necessary without
            rounding (otherwise, the value would not be consistent with
            the seconds given by `S'). Note that GPC's TimeStamp
            currently provides for microsecond resolution, so there are
            at most 6 valid digits (which is also the default width), any
            further digits will be 0 (but if TimeStamp will ever change,
            this format will be adjusted). However, the actual resolution
            provided by the operating system via GetTimeStamp etc. may be
            far lower (e.g., ~1/18s under Dos).
     
       `r'  The complete time using the AM/PM format of the current
            locale.
     
       `R'  The hour and minute in decimal numbers using the format
            `%H:%M'.
     
       `s'  The number of seconds since the epoch, i.e., since 1970-01-01
            00:00:00 UTC (Unix time). Leap seconds are not counted unless
            leap second support is available.
     
       `S'  The seconds as a decimal number (`00' .. `60').
     
       `t'  A single tab character.
     
       `T'  The time using decimal numbers using the format `%H:%M:%S'.
     
       `u'  The day of the week as a decimal number (`1' .. `7'), Monday
            being `1'.
     
       `U'  The week number of the current year as a decimal number
            (`00' .. `53'), starting with the first Sunday as the first
            day of the first week. Days preceding the first Sunday in the
            year are considered to be in week `00'.
     
       `V'  The ISO 8601:1988 week number as a decimal number
            (`01' .. `53'). ISO weeks start with Monday and end with
            Sunday. Week `01' of a year is the first week which has the
            majority of its days in that year; this is equivalent to the
            week containing the year's first Thursday, and it is also
            equivalent to the week containing January 4. Week `01' of a
            year can contain days from the previous year. The week before
            week `01' of a year is the last week (`52' or `53') of the
            previous year even if it contains days from the new year.
     
       `w'  The day of the week as a decimal number (`0' .. `6'), Sunday
            being `0'.
     
       `W'  The week number of the current year as a decimal number
            (`00' .. `53'), starting with the first Monday as the first
            day of the first week. All days preceding the first Monday in
            the year are considered to be in week `00'.
     
       `x'  The preferred date representation for the current locale, but
            without the time.
     
       `X'  The preferred time representation for the current locale, but
            with no date.
     
       `y'  The year without a century as a decimal number
            (`00' .. `99'). This is equivalent to the year modulo 100.
            NOTE: Don't use this format if it can be avoided. Things like
            this caused Y2K bugs!
     
       `Y'  The year as a decimal number, using the Gregorian calendar.
            Years before the year `1' are numbered `0', `-1', and so on.
     
       `z'  RFC 822/ISO 8601:1988 style numeric time zone (e.g., `-0600'
            or `+0100'), or nothing if no time zone is determinable.
     
       `Z'  The time zone abbreviation (empty if the time zone can't be
            determined).
     
       `%'  (i.e., an item `%%') A literal `%' character.
     }
     function  FormatTime (const Time : TimeStamp; const Format :
       String) : TString; asmname '_p_format_time';
     
     { ==================== FILE HANDLING ROUTINES ==================== }
     
     { File handling routines and their support, mostly from files.pas
       and file.c }
     
     type
       FileSizeType = LongInt;
     
     procedure GetBinding   (protected var aFile : AnyFile; var
       aBinding : BindingType); asmname '_p_binding';
     procedure ClearBinding (var aBinding : BindingType);
       asmname '_p_clearbinding';
     
     { TFDD interface @@ Subject to change! Use with caution! }
     
     type
       TOpenMode   = (foNone, foReset, foRewrite, foAppend, foSeekRead,
       foSeekWrite, foSeekUpdate);
       TOpenProc   = procedure (var PrivateData; Mode : TOpenMode);
       TSelectFunc = function  (var PrivateData; Writing : Boolean) :
       Integer; { called before select(), must return a handle }
       TSelectProc = procedure (var PrivateData; var ReadSelect,
       WriteSelect, ExceptSelect : Boolean); { called before and after
       select() }
       TReadFunc   = function  (var PrivateData; var   Buffer; Size :
       SizeType) : SizeType;
       TWriteFunc  = function  (var PrivateData; const Buffer; Size :
       SizeType) : SizeType;
       TFileProc   = procedure (var PrivateData);
       TFlushProc  = TFileProc;
       TCloseProc  = TFileProc;
       TDoneProc   = TFileProc;
     
     procedure AssignTFDD (var f : AnyFile;
                           OpenProc    : TOpenProc;
                           SelectFunc  : TSelectFunc;
                           SelectProc  : TSelectProc;
                           ReadFunc    : TReadFunc;
                           WriteFunc   : TWriteFunc;
                           FlushProc   : TFlushProc;
                           CloseProc   : TCloseProc;
                           DoneProc    : TDoneProc;
                           PrivateData : Pointer);
       asmname '_p_assign_tfdd';
     
     procedure SetTFDD    (var f : AnyFile;
                           OpenProc    : TOpenProc;
                           SelectFunc  : TSelectFunc;
                           SelectProc  : TSelectProc;
                           ReadFunc    : TReadFunc;
                           WriteFunc   : TWriteFunc;
                           FlushProc   : TFlushProc;
                           CloseProc   : TCloseProc;
                           DoneProc    : TDoneProc;
                           PrivateData : Pointer); asmname '_p_set_tfdd';
     
     { Any parameter except f may be null }
     procedure GetTFDD    (var f : AnyFile;
                           var OpenProc    : TOpenProc;
                           var SelectFunc  : TSelectFunc;
                           var SelectProc  : TSelectProc;
                           var ReadFunc    : TReadFunc;
                           var WriteFunc   : TWriteFunc;
                           var FlushProc   : TFlushProc;
                           var CloseProc   : TCloseProc;
                           var DoneProc    : TDoneProc;
                           var PrivateData : Pointer);
       asmname '_p_get_tfdd';
     
     type
       Natural = 1 .. MaxInt;
       IOSelectEvents = (SelectReadOrEOF, SelectRead, SelectEOF,
       SelectWrite, SelectException, SelectAlways);
     
     const
       IOSelectEventMin = (*Low (IOSelectEvents);*)SelectReadOrEOF;
       IOSelectEventMax = Pred (SelectAlways);
     
     type
       IOSelectType = record
         f : PAnyFile;
         Wanted : set of IOSelectEvents;
         Occurred : set of IOSelectEventMin .. IOSelectEventMax
       end;
     
     { Waits for one of several events to happen. Returns when one or
       more of the wanted events for one of the files occur. If they have
       already occurred before calling the function, it returns
       immediately. MicroSeconds can specify a timeout. If it is 0, the
       function will return immediately, whether or not an event has
       occurred. If it is negative, the function will wait forever until
       an event occurs. The Events parameter can be null, in which case
       the function only waits for the timeout. If any of the file
       pointers (f) in Events are nil or the files pointed to are closed,
       they are simply ignored for convenience.
     
       It returns the index of one of the files for which any event has
       occurred. If events have occurred for several files, is it
       undefined which of these file's index is returned. If no event
       occurs until the timeout, 0 is returned. If an error occurs or the
       target system does not have a select() system call and Events is
       not null, a negative value is returned. In the Occurred field of
       the elements of Events, events that have occurred are set. The
       state of events not wanted is undefined.
     
       The possible events are:
       SelectReadOrEOF: the file is at EOF or data can be read now.
       SelectRead:      data can be read now.
       SelectEOF:       the file is at EOF.
       SelectWrite:     data can be written now.
       SelectException: an exception occurred on the file.
       SelectAlways:    if this is set, *all* requested events will be
                        checked for this file in any case. Otherwise,
                        checks may be skipped if already another event
                        for this or another file was found.
     
       Notes:
       Checking for EOF requires some reading ahead internally (just like
       the EOF function) which can be avoided by setting SelectReadOrEOF
       instead of SelectRead and SelectEOF. If this is followed by, e.g.,
       a BlockRead with 4 parameters, the last parameter will be 0 if and
       only the file is at EOF, and otherwise, data will be read directly
       from the file without reading ahead and buffering.
     
       SelectAlways should be set for files for which events are
       considered to be of higher priority than others. Otherwise, if one
       is interested in just any event, not setting SelectAlways may be a
       little faster. }
     function IOSelect (var Events : array [m .. n : Natural] of
       IOSelectType; MicroSeconds : MicroSecondTimeType) : Integer;
       asmname '_p_ioselect';
     
     { A simpler interface to SelectIO for the most common use. Waits for
       SelectReadOrEOF on all files and returns an index. }
     function IOSelectRead (const Files : array [m .. n : Natural] of
       PAnyFile; MicroSeconds : MicroSecondTimeType) : Integer;
       asmname '_p_ioselectread';
     
     procedure AssignFile   (var T : AnyFile; const Name : String);
       asmname '_p_assign';
     procedure AssignBinary (var T : Text; const Name : String);
       asmname '_p_assign_binary';
     procedure AssignHandle (var T : AnyFile; Handle : Integer);
       asmname '_p_assign_handle';
     
     { BP compatible seeking routines }
     function  SeekEOF  (var f : Text) : Boolean; asmname '_p_seekeof';
     function  SeekEOLn (var f : Text) : Boolean; asmname '_p_seekeoln';
     
     { Under development }
     procedure AnyStringTFDD_Reset (var f : AnyFile; var Buf :
       ConstAnyString); asmname '_p_anystring_tfdd_reset';
     (*procedure AnyStringTFDD_Rewrite (var f : AnyFile; var Buf :
       VarAnyString); asmname '_p_anystring_tfdd_rewrite';*)
     procedure StringTFDD_Reset (var f : AnyFile; var Buf :
       ConstAnyString; const s : String); asmname '_p_string_tfdd_reset';
     (*procedure StringTFDD_Rewrite (var f : AnyFile; var Buf :
       VarAnyString; var s : String); asmname '_p_string_tfdd_rewrite';*)
     
     (*@@iocritical*)procedure FileMove (var f : AnyFile; NewName :
       CString; Overwrite : Boolean); asmname '_p_mv';
     
     { Flags that can be ORed into FileMode. The default value of
       FileMode is FileMode_Reset_ReadWrite. The somewhat confusing
       values are meant to be compatible to BP (as far as BP supports
       them). }
     const
       { Allow writing to binary files opened with Reset }
       FileMode_Reset_ReadWrite      = 2;
     
       { Do not allow reading from files opened with Rewrite }
       FileMode_Rewrite_WriteOnly    = 4;
     
       { Do not allow reading from files opened with Extend }
       FileMode_Extend_WriteOnly     = 8;
     
       { Allow writing to text files opened with Reset }
       FileMode_Text_Reset_ReadWrite = $100;
     
     { File mode constants that are ORed for BindingType.Mode and ChMod.
       The values below are valid for all OSs (as far as supported). If
       the OS uses different values, they're converted internally. }
     const
       fm_SetUID           = 8#4000;
       fm_SetGID           = 8#2000;
       fm_Sticky           = 8#1000;
       fm_UserReadable     = 8#400;
       fm_UserWritable     = 8#200;
       fm_UserExecutable   = 8#100;
       fm_GroupReadable    = 8#40;
       fm_GroupWritable    = 8#20;
       fm_GroupExecutable  = 8#10;
       fm_OthersReadable   = 8#4;
       fm_OthersWritable   = 8#2;
       fm_OthersExecutable = 8#1;
     
     type
       TextFile = Text;
     
       StatFSBuffer = record
         BlockSize, BlocksTotal, BlocksFree : LongestInt;
         FilesTotal, FilesFree : Integer
       end;
     
     procedure CloseFile    (          var aFile : (*@@Any*)File);
       asmname '_p_close';
     (*@@IO critical*) procedure ChMod        (          var aFile :
       AnyFile; Mode : Integer); asmname '_p_chmod';
     (*@@IO critical*) procedure StatFS       (Path : CString; var Buf :
       StatFSBuffer); asmname '_p_statfs';
     
     { Checks if data are available to be read from aFile. This is
       similar to
       `not EOF (aFile)', but does not block on "files" that can grow,
       like TTYs
       or pipes. }
     function  CanRead      (var aFile : AnyFile) : Boolean;
       asmname '_p_canread';
     
     { Get the file handle. }
     function  FileHandle   (protected var aFile : AnyFile) : Integer;
       asmname '_p_filehandle';
     
     { The following routine is meant *only* as a work-around for a
       problem under IRIX where writing reals with Write/Writeln/WriteStr
       does not work. This function will disappear after the problem has
       been solved. Width and Prec are the formatting parameters
       specified after `:'s in Write. If not wanted, NoWidth and
       NoPrecision can be passed. }
     const
       NoWidth = Low (Integer);
       NoPrecision = Low (Integer);
     function  LongReal2Str (Num : LongReal; Width, Prec : Integer) :
       TString; asmname '_p_longreal2str';
     
     function  FileLock   (var aFile : AnyFile; WriteLock, Block :
       Boolean) : Boolean; asmname '_p_filelock';
     function  FileUnlock (var aFile : AnyFile) : Boolean;
       asmname '_p_fileunlock';
     
     const
       mm_Readable   = 1;
       mm_Writable   = 2;
       mm_Executable = 4;
     
     function MemoryMap (Start : Pointer; Length : SizeType; Access :
       Integer; Shared : Boolean;
                         var aFile : AnyFile; Offset : FileSizeType) :
       Pointer; asmname '_p_mmap';
     procedure MemoryUnMap (Start : Pointer; Length : SizeType);
       asmname '_p_munmap';
     
     { File name routines, from filename.pas }
     
     {
       Define constants for different systems:
     
       OSDosFlag:         flag to indicate whether the target system is
                          Dos
     
       QuotingCharacter:  the character used to quote wild cards and
                          other special characters (#0 if not available)
     
       PathSeparator:     the separator of multiple paths, e.g. in the
                          PATH environment variable
     
       DirSeparator:      the separator of the directories within a full
                          file name
     
       DirSeparators:     a set of all possible directory and drive name
                          separators
     
       ExtSeparator:      the separator of a file name extension
     
       DirRoot:           the name of the root directory
     
       DirSelf:           the name of a directory in itself
     
       DirParent:         the name of the parent directory
     
       MaskNoStdDir:      a file name mask that matches all names except
                          the standard directories DirSelf and DirParent
     
       NullDeviceName:    the full file name of the null device
     
       TTYDeviceName:     the full file name of the current TTY
     
       ConsoleDeviceName: the full file name of the system console. On
                          Dos systems, this is the same as the TTY, but
                          on systems that allow remote login, this is a
                          different thing and may reach a completely
                          different user than the one running the
                          program, so use with care.
     
       EnvVarCharsFirst:  the characters accepted at the beginning of the
                          name of an environment variable without quoting
     
       EnvVarChars:       the characters accepted in the name of an
                          environment variable without quoting
     
       PathEnvVar:        the name of the environment variable which
                          (usually) contains the executable search path
     
       ShellEnvVar:       the name of the environment variable which
                          (usually) contains the path of the shell
                          executable (see GetShellPath)
     
       ShellExecCommand:  the option to the (default) shell to execute
                          the command specified in the following argument
                          (see GetShellPath)
     
       ConfigFileMask:    a mask for the option file name as returned by
                          ConfigFileName
     
       FileNamesCaseSensitive:
                          flag to indicate whether file names are case
                          sensitive
     }
     
     const
       UnixShellEnvVar        = 'SHELL';
       UnixShellExecCommand   = '-c';
     
     {$ifdef __OS_DOS__}
     
     const
       OSDosFlag              = True;
       QuotingCharacter       = #0;
       PathSeparator          = {$ifdef __CYGWIN32__} ':' {$else} ';'
       {$endif};
       DirSeparator           = '\';
       DirSeparators          = [':', '\', '/'];
       ExtSeparator           = '.';
       DirRoot                = '\';
       DirSelf                = '.';
       DirParent              = '..';
       MaskNoStdDir           = '{*,.[^.],..?*}';
       NullDeviceName         = 'nul';
       TTYDeviceName          = 'con';
       ConsoleDeviceName      = 'con';
       EnvVarCharsFirst       = ['A' .. 'Z', 'a' .. 'z', '_'];
       EnvVarChars            = EnvVarCharsFirst + ['0' .. '9'];
       PathEnvVar             = 'PATH';
       ShellEnvVar            = 'COMSPEC';
       ShellExecCommand       = '/c';
       ConfigFileMask         = '*.cfg';
       FileNamesCaseSensitive = False;
     
     {$else}
     
     const
       OSDosFlag              = False;
       QuotingCharacter       = '\';
       PathSeparator          = ':';
       DirSeparator           = '/';
       DirSeparators          = ['/'];
       ExtSeparator           = '.';
       DirRoot                = '/';
       DirSelf                = '.';
       DirParent              = '..';
       MaskNoStdDir           = '{*,.[^.],..?*}';
       NullDeviceName         = '/dev/null';
       TTYDeviceName          = '/dev/tty';
       ConsoleDeviceName      = '/dev/console';
       EnvVarCharsFirst       = ['A' .. 'Z', 'a' .. 'z', '_'];
       EnvVarChars            = EnvVarCharsFirst + ['0' .. '9'];
       PathEnvVar             = 'PATH';
       ShellEnvVar            = UnixShellEnvVar;
       ShellExecCommand       = UnixShellExecCommand;
       ConfigFileMask         = '.*';
       FileNamesCaseSensitive = True;
     
     {$endif}
     
     const
       WildCardChars = ['*', '?', '[', ']'];
       FileNameSpecialChars = (WildCardChars + SpaceCharacters +
       ['{', '}', '$', QuotingCharacter]) - DirSeparators;
     
     type
       DirPtr = Pointer;
     
       { `+ 1' is a waste, but it is so the size of the array is not
         zero for Count = 0 }
       PPStrings = ^TPStrings;
       TPStrings (Count : Cardinal) = array [1 .. Count + 1] of ^String;
     
       GlobBuffer = record
         Result    : PPStrings;
         Internal1 : Pointer;
         Internal2 : PCStrings;
         Internal3 : Integer
       end;
     
     { Convert ch to lower case if FileNamesCaseSensitive is False, leave
       it unchanged otherwise. }
     function  FileNameLoCase (ch : Char) : Char;
       asmname '_p_filenamelocase';
     
     { Change a file name to use the OS dependent directory separator }
     function  Slash2OSDirSeparator (const s : String) : TString;
       asmname '_p_slash2osdirseparator';
     
     { Change a file name to use '/' as directory separator }
     function  OSDirSeparator2Slash (const s : String) : TString;
       asmname '_p_osdirseparator2slash';
     
     { Like Slash2OSDirSeparator for CStrings -- NOTE: overwrites the
       CString }
     function  Slash2OSDirSeparator_CString (s : CString) : CString;
       asmname '_p_slash2osdirseparator_cstring';
     
     { Like OSDirSeparator2Slash for CStrings -- NOTE: overwrites the
       CString }
     function  OSDirSeparator2Slash_CString (s : CString) : CString;
       asmname '_p_osdirseparator2slash_cstring';
     
     { Add a DirSeparator to the end of s, if there is not already one
       and s denotes an existing directory }
     function  AddDirSeparator (const s : String) : TString;
       asmname '_p_adddirseparator';
     
     { Like AddDirSeparator, but also if the directory does not exist }
     function  ForceAddDirSeparator (const s : String) : TString;
       asmname '_p_forceadddirseparator';
     
     { Remove all trailing DirSeparators from s, if there are any, as
       long as removing them doesn't change the meaning (i.e., they don't
       denote the root directory. }
     function  RemoveDirSeparator (const s : String) : TString;
       asmname '_p_removedirseparator';
     
     { Returns the current directory using OS dependent directory
       separators }
     function  GetCurrentDirectory     : TString;
       asmname '_p_get_current_directory';
     
     { Returns a directory suitable for storing temporary files using OS
       dependent directory separators. If found, the result always ends
       in DirSeparator. If no suitable directory is found, an empty
       string is returned. }
     function  GetTempDirectory        : TString;
       asmname '_p_get_temp_directory';
     
     { Returns a non-existing file name in the directory given. If the
       directory doesn't exist or the Directory name is empty, a runtime
       error is raised, and GetTempFileNameInDirectory returns the empty
       string. }
     (*@@iocritical*)function  GetTempFileNameInDirectory (const
       Directory : String) : TString;
       asmname '_p_get_temp_file_name_in_directory';
     
     { Returns a non-existing file name in GetTempDirectory. If no temp
       directory is found, i.e. GetTempDirectory returns the empty
       string, a runtime error is raised, and GetTempFileName returns the
       empty string as well. }
     (*@@iocritical*)function  GetTempFileName         : TString;
       asmname '_p_get_temp_file_name';
     
     { The same as GetTempFileName, but returns a CString allocated from
       the heap. }
     (*@@iocritical*)function  GetTempFileName_CString : CString;
       asmname '_p_get_temp_file_name_cstring';
     
     { Get the external name of a file }
     function  FileName (protected var f : AnyFile) : TString;
       asmname '_p_file_name';
     
     { Returns true if the given file name is an existing plain file }
     function  FileExists      (const aFileName : String) : Boolean;
       asmname '_p_file_exists';
     
     { Returns True if the given file name is an existing directory }
     function  DirectoryExists (const aFileName : String) : Boolean;
       asmname '_p_directory_exists';
     
     { Returns True if the given file name is an existing file, directory
       or special file (device, pipe, socket, etc.) }
     function  PathExists      (const aFileName : String) : Boolean;
       asmname '_p_path_exists';
     
     { If a file of the given name exists in one of the directories given
       in DirList (separated by PathSeparator), returns the full path,
       otherwise returns an empty string. If aFileName already contains
       an element of DirSeparators, returns Slash2OSDirSeparator
       (aFileName) if it exists. }
     function  FSearch (const aFileName, DirList : String) : TString;
       asmname '_p_fsearch';
     
     { Like FSearch, but only find executable files. Under Dos, if not
       found, the function tries appending '.com', '.exe', '.bat' and
       `.cmd' (the last one only if $COMSPEC points to a `cmd.exe'), so
       you don't have to specify these extensions in aFileName (and with
       respect to portability, it might be preferable not to do so). }
     function  FSearchExecutable (const aFileName, DirList : String) :
       TString; asmname '_p_fsearch_executable';
     
     { Replaces all occurrences of `$FOO' and `~' in s by the value of
       the environment variables FOO or HOME, respectively. If a variable
       is not defined, the function returns False, and s contains the
       name of the undefined variable (or the empty string if the
       variable name is invalid, i.e., doesn't start with a character
       from EnvVarCharsFirst). Otherwise, if all variables are found, s
       contains the replaced string, and True is returned. }
     function  ExpandEnvironment (var s : String) : Boolean;
       asmname '_p_expand_environment';
     
     { Expands the given path name to a full path name. Relative paths
       are expanded using the current directory, and occurrences of
       DirSelf and DirParent are resolved. Under Dos, the result is
       converted to lower case and a trailing ExtSeparator (except in a
       trailing DirSelf or DirParent) is removed, like Dos does. If the
       directory, i.e. the path without the file name, is invalid, the
       empty string is returned. }
     function  FExpand       (const Path : String) : TString;
       asmname '_p_fexpand';
     
     { Like FExpand, but unquotes the directory before expanding it, and
       quotes WildCardChars again afterwards. Does not check if the
       directory is valid (because it may contain wild card characters).
       Symlinks are expanded only in the directory part, not the file
       name. }
     function  FExpandQuoted (const Path : String) : TString;
       asmname '_p_fexpandquoted';
     
     { FExpands Path, and then removes the current directory from it, if
       it is a prefix of it. If OnlyCurDir is set, the current directory
       will be removed only if Path denotes a file in, not below, it. }
     function  RelativePath (const Path : String; OnlyCurDir, Quoted :
       Boolean) : TString; asmname '_p_relative_path';
     
     { Is aFileName a UNC filename? (Always returns False on non-Dos
       systems.) }
     function  IsUNC (const aFileName : String) : Boolean;
       asmname '_p_IsUNC';
     
     { Splits a file name into directory, name and extension. Each of
       Dir, Name and Ext may be null. }
     procedure FSplit (const Path : String; var Dir, Name, Ext : String);
       asmname '_p_fsplit';
     
     { Functions that extract one or two of the parts from FSplit.
       DirFromPath returns DirSelf + DirSeparator if the path contains no
       directory. }
     function  DirFromPath     (const Path : String) : TString;
       asmname '_p_dir_from_path';
     function  NameFromPath    (const Path : String) : TString;
       asmname '_p_name_from_path';
     function  ExtFromPath     (const Path : String) : TString;
       asmname '_p_ext_from_path';
     function  NameExtFromPath (const Path : String) : TString;
       asmname '_p_name_ext_from_path';
     
     { Start reading a directory. If successful, a pointer is returned
       that can be used for subsequent calls to ReadDir and finally
       CloseDir. On failure, an I/O error is raised and (in case it is
       ignored) nil is returned. }
     (*@@iocritical*)function  OpenDir  (const Name : String) : DirPtr;
       asmname '_p_opendir';
     
     { Reads one entry from the directory Dir, and returns the file name.
       On errors or end of directory, the empty string is returned. }
     function  ReadDir  (Dir : DirPtr) : TString; asmname '_p_readdir';
     
     { Closes a directory opened with OpenDir. }
     (*@@iocritical*)procedure CloseDir (Dir : DirPtr);
       asmname '_p_closedir';
     
     { Returns the first position of a non-quoted character of CharSet in
       s, or 0 if no such character exists. }
     function  FindNonQuotedChar (Chars : CharSet; const s : String;
       From : Integer) : Integer; asmname '_p_findnonquotedchar';
     
     { Returns the first occurence of SubString in s that is not quoted
       at the beginning, or 0 if no such occurence exists. }
     function  FindNonQuotedStr (const SubString, s : String; From :
       Integer) : Integer; asmname '_p_findnonquotedstr';
     
     { Does a string contain non-quoted wildcard characters? }
     function  HasWildCards (const s : String) : Boolean;
       asmname '_p_haswildcards';
     
     { Does a string contain non-quoted wildcard characters, braces or
       spaces? }
     function  HasWildCardsOrBraces (const s : String) : Boolean;
       asmname '_p_haswildcardsorbraces';
     
     { Insert QuotingCharacter into s before any special characters }
     function  QuoteFileName (const s : String; const SpecialCharacters :
       CharSet) : TString; asmname '_p_quote_filename';
     
     { Remove QuotingCharacter from s }
     function  UnQuoteFileName (const s : String) : TString;
       asmname '_p_unquote_filename';
     
     { Splits s at non-quoted spaces and expands non-quoted braces like
       bash does. The result and its entries should be disposed after
       usage, e.g. with DisposePPStrings. }
     function  BraceExpand (const s : String) : PPStrings;
       asmname '_p_braceexpand';
     
     { Dispose of a PPStrings array as well as the strings it contains.
       If you want to keep the strings (by assigning them to other string
       pointers), you should instead free the PPStrings array with
       `Dispose'. }
     procedure DisposePPStrings (Strings : PPStrings);
       asmname '_p_DisposePPStrings';
     
     { Tests if a file name matches a shell wildcard pattern (?, *, []) }
     function  FileNameMatch (const Pattern, Name : String) : Boolean;
       asmname '_p_filenamematch';
     
     { FileNameMatch with BraceExpand }
     function  MultiFileNameMatch (const Pattern, Name : String) :
       Boolean; asmname '_p_multifilenamematch';
     
     { File name globbing }
     { GlobInit is implied by Glob and MultiGlob, not by GlobOn and
       MultiGlobOn. GlobOn and MultiGlobOn must be called after GlobInit,
       Glob or MultiGlob. MultiGlob and MultiGlobOn do brace expansion,
       Glob and GlobOn do not. GlobFree frees the memory allocated by the
       globbing functions and invalidates the results in Buf. It should
       be called after globbing. }
     procedure GlobInit    (var Buf : GlobBuffer); asmname '_p_globinit';
     procedure Glob        (var Buf : GlobBuffer; const Pattern :
       String); asmname '_p_glob';
     procedure GlobOn      (var Buf : GlobBuffer; const Pattern :
       String); asmname '_p_globon';
     procedure MultiGlob   (var Buf : GlobBuffer; const Pattern :
       String); asmname '_p_multiglob';
     procedure MultiGlobOn (var Buf : GlobBuffer; const Pattern :
       String); asmname '_p_multiglobon';
     procedure GlobFree    (var Buf : GlobBuffer); asmname '_p_globfree';
     
     type
       TPasswordEntry = record
         UserName, RealName, Password, HomeDirectory, Shell : TString;
         UID, GID : Integer
       end;
     
       PPasswordEntries = ^TPasswordEntries;
       TPasswordEntries (Count : Integer) = array [1 .. Count] of
       TPasswordEntry;
     
     { Finds a password entry by user name. Returns True if found, False
       otherwise. }
     function  GetPasswordEntryByName (const UserName : String; var
       Entry : TPasswordEntry) : Boolean;
       asmname '_p_getpasswordentrybyname';
     
     { Finds a password entry by UID. Returns True if found, False
       otherwise. }
     function  GetPasswordEntryByUID  (UID : Integer; var Entry :
       TPasswordEntry) : Boolean; asmname '_p_getpasswordentrybyuid';
     
     { Returns all password entries, or nil if none found. }
     function  GetPasswordEntries : PPasswordEntries;
       asmname '_p_getpasswordentries';
     
     { Returns the mount point (Unix) or drive (Dos) which is part of the
       given path. If the path does not contain any (i.e., is a relative
       path), an empty string is returned. Therefore, if you want to get
       the mount point or drive in any case, apply `FExpand' or
       `RealPath' to the argument. }
     function  GetMountPoint (const Path : String) = Result : TString;
       asmname '_p_GetMountPoint';
     
     type
       TSystemInfo = record
         OSName,
         OSRelease,
         OSVersion,
         MachineType,
         HostName,
         DomainName : TString
       end;
     
     { Returns system information if available. Fields not available will
       be empty. }
     function  SystemInfo : TSystemInfo; asmname '_p_SystemInfo';
     
     { Returns the path to the shell (as the return value) and the option
       that makes it execute the command specified in the following
       argument (in `Option'). Usually these are the environment value of
       ShellEnvVar, and ShellExecCommand, but on Dos systems, the
       function will first try UnixShellEnvVar, and UnixShellExecCommand
       because ShellEnvVar will usually point to command.com, but
       UnixShellEnvVar can point to bash which is usually a better choice
       when present. If UnixShellEnvVar is not set, or the shell given
       does not exist, it will use ShellEnvVar, and ShellExecCommand.
       Option may be null (in case you want to invoke the shell
       interactively). }
     function  GetShellPath (var Option : String) : TString;
       asmname '_p_GetShellPath';
     
     { Returns the path of the running executable. NOTE: On most systems,
       this is *not* guaranteed to be the full path, but often just the
       same as `ParamStr (0)' which usually is the name given on the
       command line. Only on some systems with special support, it
       returns the full path when `ParamStr (0)' doesn't. }
     function  ExecutablePath : TString; asmname '_p_executable_path';
     
     { Returns a file name suitable for a global (system-wide) or local
       (user-specific) configuration file, depending on the Global
       parameter. The function does not guarantee that the file name
       returned exists or is readable or writable.
     
       In the following table, the base name `<base>' is given with the
       Name parameter. If it is empty, the base name is the name of the
       running program (as returned by ExecutablePath, without directory
       and extension. `<prefix>' (Unix only) stands for the value of the
       Prefix parameter (usual values include '', '/usr' and
       '/usr/local'). `<dir>' (Dos only) stands for the directory where
       the running program resides. `$foo' stands for the value of the
       environment variable `foo'.
     
              Global                    Local
       Unix:  <prefix>/etc/<base>.conf  $HOME/.<base>
     
       Dos:   $DJDIR\etc\<base>.ini     $HOME\<base>.cfg
              <dir>\<base>.ini          <dir>\<base>.cfg
     
       As you see, there are two possibilities under Dos. If the first
       file exists, it is returned. Otherwise, if the second file exists,
       that is returned. If none of them exists (but the program might
       want to create a file), if the environment variable (DJDIR or
       HOME, respectively) is set, the first file name is returned,
       otherwise the second one. This rather complicated scheme should
       give the most reasonable results for systems with or without DJGPP
       installed, and with or without already existing config files. Note
       that DJDIR is always set on systems with DJGPP installed, while
       HOME is not. However, it is easy for users to set it if they want
       their config files in a certain directory rather than with the
       executables. }
     function  ConfigFileName (const Prefix, Name : String; Global :
       Boolean) : TString; asmname '_p_config_file_name';
     
     { Returns a directory name suitable for global, machine-independent
       data. The function garantees that the name returned ends with a
       DirSeparator, but does not guarantee that it exists or is
       readable or writable.
     
       Note: If the prefix is empty, it is assumed to be '/usr'. (If you
       really want /share, you could pass '/' as the prefix, but that's
       very uncommon.)
     
       Unix: <prefix>/share/<base>/
     
       Dos:  $DJDIR\share\<base>\
             <dir>\
     
       About the symbols used above, and the two possibilities under Dos,
       see the comments for ConfigFileName. }
     function  DataDirectoryName (const Prefix, Name : String) : TString;
       asmname '_p_data_directory_name';
     
     { ==================== MATHEMATICAL ROUTINES ===================== }
     
     function  IsInfinity   (x : Extended) : Boolean; attribute (const);
       asmname '_p_isinf';
     function  IsNotANumber (x : Extended) : Boolean; attribute (const);
       asmname '_p_isnan';
     procedure SplitReal    (x : Extended; var Exponent : Integer; var
       Mantissa : Extended); asmname '_p_frexp';
     function  SinH         (x : Double)    : Double; asmname '_p_sinh';
     function  CosH         (x : Double)    : Double; asmname '_p_cosh';
     function  Arctan2      (y, x : Double) : Double;
       asmname '_p_arctan2';
     
     type
       RandomSeedType = Cardinal (32);
       RandomizeType  = ^procedure;
       SeedRandomType = ^procedure (Seed : RandomSeedType);
       RandRealType   = ^function : LongestReal;
       RandIntType    = ^function (MaxValue : LongestCard) : LongestCard;
     
     var
       RandomizePtr  : RandomizeType; asmname '_p_randomize_ptr';
       external;
       SeedRandomPtr : SeedRandomType; asmname '_p_seedrandom_ptr';
       external;
       RandRealPtr   : RandRealType; asmname '_p_randreal_ptr'; external;
       RandIntPtr    : RandIntType; asmname '_p_randint_ptr'; external;
     
     procedure SeedRandom (Seed : RandomSeedType);
       asmname '_p_seedrandom';
     
     end.


File: gpc,  Node: GPC Units,  Prev: Run Time System,  Up: Programming

7.13 Units included with GPC
============================

   GPC distributions now include a number of useful Pascal units and a
complete set of BP compatibility units - except for the `Graph' unit
(which is currently distributed separately due to its license) and the
OOP stuff. The main use of these units is to provide a way to port BP
programs to GPC as easily as possible. Some of the units also implement
functionaliy not available otherwise.

   Most of the BP compatibility units - except `CRT' and `Printer' -
are merely meant to let programs written for BP compile with GPC as
easily as possible. They should not be used in newly written code, and
for code ported from BP to GPC, it is suggested to replace them
successively with the more powerful - and often easier to use -
alternatives that GPC's Run Time System (*note Run Time System::)
offers.

   The following sections describe all units included with GPC (besides
the `GPC' module which describes the interface to the Run Time System,
*Note Run Time System::).

* Menu:

* CRT::          BP compatibility: CRT & WinCRT, portable, with many extensions
* Dos::          BP compatibility: Dos
* DosUnix::      Overcome some differences between Dos and Unix
* FileUtils::    Higher level file and directory handling
* GMP::          Arithmetic with unlimited size and precision
* GPCUtil::      Turbo Power compatibility, etc.
* HeapMon::      Primitive heap checking
* MD5::          `MD5' Message Digests
* Overlay::      BP compatibility: Overlay
* Pipe::         Start a child process, connected with pipes, also on Dos
* Ports::        BP compatibility (partly): `Port', `PortW' arrays
* Printer::      BP compatibility: Printer, portable
* RegEx::        Regular Expression matching and substituting
* Strings::      BP compatibility: Strings
* StringUtils::  Higher level string handling
* System::       BP compatibility: System
* Trap::         Trap runtime errors
* Turbo3::       BP compatibility: Turbo3
* WinDos::       BP compatibility: WinDos


File: gpc,  Node: CRT,  Next: Dos,  Up: GPC Units

7.13.1 BP compatibility: CRT & WinCRT, portable, with many extensions
---------------------------------------------------------------------

   The following listing contains the interface of the CRT unit.

   `CRT' is a `curses' based unit for text screen handling.  It is
compatible to BP's `CRT' unit, even in a lot of minor details like the
values of function key codes and includes some routines for
compatibility with TP5's `Win' unit as well as BP's `WinCrt' and Turbo
Power's `TPCrt' units, and some extensions.

   The unit has been extended by many functions that were lacking in
BP's unit and required assembler code or direct memory/port access to
be implemented under BP. The GPC version is now fully suited for
portable, real-world programming without any dirty tricks.

   The unit is also available as `WinCRT', completely identical to
`CRT'. The only purpose of this "feature" is to let programs written
for TPW or BP, with a `uses WinCRT' directive, compile without changes.
Unlike TPW/BP's `WinCRT' unit, GPC's unit is not crippled, compared to
`CRT'.

   To use this unit, you will need the `ncurses' (version 5.0 or newer)
or `PDCurses' library which can be found in
`ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/'.

     {
     CRT (Crt Replacement Tool)
     Portable BP compatible CRT unit for GPC with many extensions
     
     This unit is aware of terminal types. This means programs using this
     unit will work whether run locally or while being logged in remotely
     from a system with a completely different terminal type (as long as
     the appropriate terminfo entry is present on the system where the
     program is run).
     
     NOTES:
     
     - The CRT unit needs the ncurses and panel libraries which should be
       available for almost any system. For Dos systems, where ncurses is
       not available, it is configured to use the PDCurses and its panel
       library instead. On Unix systems with X11, it can also use
       PDCurses (xcurses) and xpanel to produce X11 programs. The
       advantage is that the program won't need an xterm with a valid
       terminfo entry, the output may look a little nicer and function
       keys work better than in an xterm, but the disadvantage is that it
       will only run under X. The ncurses and PDCurses libraries
       (including panel and xpanel, resp.) can be found in
       ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/
       (Note that ncurses is already installed on many Unix systems.) For
       ncurses, version 5.0 or newer is strongly recommended because
       older versions contain a bug that severely affects CRT programs.
     
       When an X11 version under Unix is wanted, give `-DX11' when
       compiling crt.pas and crtc.c (or when compiling crt.pas or a
       program that uses CRT with `--automake'). On pre-X11R6 systems,
       give `-DNOX11R6' additionally. You might also have to give the
       path to the X11 libraries with `-L', e.g. `-L /usr/X11/lib'.
     
     - A few features cannot be implemented in a portable way and are
       only available on some systems:
     
           Sound, NoSound 1)                  -----------------------.
           GetShiftState                      ------------------.    |
           TextMode etc. 2)                   -------------.    |    |
           CRTSavePreviousScreen              --------.    |    |    |
           Interrupt signal (Ctrl-C) handling ---.    |    |    |    |
                                                 |    |    |    |    |
       Linux/x86 3) (terminal)                   X    X 4) X 5) X 6) X 6)
       Other Unix (terminal)                     X    X 7) X 5) -    -
       Unix (X11 version)                        X    X    - 8) X    -
       Dos (DJGPP)                               X    X    X    X    X
       MS-Windows (Cygwin or mingw)              X    -    X 9) X    -
     
       Notes:
     
       1) If you define NO_CRT_DUMMY_SOUND while compiling CRT, you will
          get linking errors when your program tries to use Sound/NoSound
          on a platform where it's not supported (which is useful to
          detect at compile time if playing sound is a major task of your
          program). Otherwise, Sound/NoSound will simply do nothing
          (which is usually acceptable if the program uses these routines
          just for an occasional beep).
     
       2) Changing to monochrome modes works on all platforms. Changing
          the screen size only works on those indicated. However, even on
          the platforms not supported, the program will react to screen
          size changes by external means (e.g. changing the window size
          with the mouse if running in a GUI window or resizing a console
          or virtual terminal).
     
       3) Probably also on other processors, but I've had no chance to
          test this yet.
     
       4) Only on a local console with access permissions to the
          corresponding virtual console memory device or using the
          `crtscreen' utility (see crtscreen.c in the demos directory).
     
       5) Only if supported by an external command (e.g., in xterms and
          on local Linux consoles). The command to be called can be
          defined in the environment variable `RESIZETERM' (where the
          variables `columns' and `lines' in the command are set to the
          size wanted). If not set, the code will try `resize -s' in an
          xterm and otherwise `SVGATextMode' and `setfont'. For this to
          work, these utilities need to be present in the PATH or
          `/usr/sbin' or `/usr/local/sbin'. Furthermore, SVGATextMode and
          setfont require root permissions, either to the executable of
          the program compiled with CRT or to resizecons (called by
          setfont) or SVGATextMode. To allow the latter, do
          "chmod u+s `which resizecons`" and/or
          "chmod u+s `which SVGATextMode`", as root once, but only if you
          really want each user to be allowed to change the text mode.
     
       6) Only on local consoles.
     
       7) Some terminals only. Most xterms etc. support it as well as
          other terminals that support an "alternate screen" in the
          smcup/rmcup terminal capabilities.
     
       8) But the user can resize the window.
     
       9) Only with PDCurses, not with ncurses. Changing the number of
          screen *columns* doesn't work in a full-screen session.
     
     - When CRT is initialized (automatically or explicitly; see the
       comments for CRTInit), the screen is cleared, and at the end of
       the program, the cursor is placed at the bottom of the screen
       (curses behaviour).
     
     - All the other things (including most details like color and
       function key constants) are compatible with BP's CRT unit, and
       there are many extensions that BP's unit does not have.
     
     - When the screen size is changed by an external event (e.g.,
       resizing an xterm or changing the screen size from another VC
       under Linux), the virtual "function key" kbScreenSizeChanged is
       returned. Applications can use the virtual key to resize their
       windows. kbScreenSizeChanged will not be returned if the screen
       size change was initiated by the program itself (by using TextMode
       or SetScreenSize). Note that TextMode sets the current panel to
       the full screen size, sets the text attribute to the default and
       clears the window (BP compatibility), while SetScreenSize does
       not.
     
     - After the screen size has been changed, whether by using TextMode,
       SetScreenSize or by an external event, ScreenSize will return the
       new screen size. The current window and all panels will have been
       adjusted to the new screen size. This means, if their right or
       lower ends are outside the new screen size, the windows are moved
       to the left and/or top as far as necessary. If this is not enough,
       i.e., if they are wider/higher than the new screen size, they are
       shrinked to the total screen width/height. When the screen size is
       enlarged, window sizes are not changed, with one exception:
       Windows that extend through the whole screen width/height are
       enlarged to the whole new screen width/height (in particular,
       full-screen windows remain full-screen). This behaviour might not
       be optimal for all purposes, but you can always resize your
       windows in your application after the screen size change.
     
     - (ncurses only) The environment variable `ESCDELAY' specifies the
       number of milliseconds allowed between an `Esc' character and the
       rest of an escape sequence (default 1000). Setting it to a value
       too small can cause problems with programs not recognizing escape
       sequences such as function keys, especially over slow network
       connections. Setting it to a value too large can delay the
       recognition of an `ESC' key press notably. On local Linux
       consoles, e.g., 10 seems to be a good value.
     
     - When trying to write portable programs, don't rely on exactly the
       same look of your output and the availability of all the key
       combinations. Some kinds of terminals support only some of the
       display attributes and special characters, and usually not all of
       the keys declared are really available. Therefore, it's safer to
       provide the same function on different key combinations and to not
       use the more exotic ones.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     
     Please also note the license of the curses library used.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit {$ifdef THIS_IS_WINCRT} WinCRT {$else} CRT {$endif};
     
     interface
     
     uses GPC;
     
     const
       { CRT modes }
       BW40          = 0;            { 40x25 Black/White }
       CO40          = 1;            { 40x25 Color }
       BW80          = 2;            { 80x25 Black/White }
       CO80          = 3;            { 80x25 Color }
       Mono          = 7;            { 80x25 Black/White }
       Font8x8       = 256;          { Add-in for 80x43 or 80x50 mode }
     
       { Mode constants for Turbo Pascal 3.0 compatibility }
       C40           = CO40;
       C80           = CO80;
     
       { Foreground and background color constants }
       Black         = 0;
       Blue          = 1;
       Green         = 2;
       Cyan          = 3;
       Red           = 4;
       Magenta       = 5;
       Brown         = 6;
       LightGray     = 7;
     
       { Foreground color constants }
       DarkGray      = 8;
       LightBlue     = 9;
       LightGreen    = 10;
       LightCyan     = 11;
       LightRed      = 12;
       LightMagenta  = 13;
       Yellow        = 14;
       White         = 15;
     
       { Add-in for blinking }
       Blink         = 128;
     
     type
       TTextAttr = Byte;
     
     var
       { If False (default: True), catch interrupt signals (SIGINT;
         Ctrl-C), and other flow control characters as well as SIGTERM,
         SIGHUP and perhaps other signals }
       CheckBreak  : Boolean = True; asmname 'crt_CheckBreak';
     
       { If True (default : False), replace Ctrl-Z by #0 in input }
       CheckEOF    : Boolean = False; asmname 'crt_CheckEOF';
     
       { Ignored -- meaningless in this context }
       DirectVideo : Boolean = True;
     
       { Ignored -- curses or the terminal driver will take care of that
         when necessary }
       CheckSnow   : Boolean = False;
     
       { Current (sic!) text mode }
       LastMode    : Word = 3; asmname 'crt_LastMode';
     
       { Current text attribute }
       TextAttr    : TTextAttr = 7; asmname 'crt_TextAttr';
     
       { Window upper left coordinates. *Obsolete*! Please see WindowMin
         below. }
       WindMin     : Word = not Word (0); asmname 'crt_WindMin';
     
       { Window lower right coordinates. *Obsolete*! Please see WindowMax
         below. }
       WindMax     : Word = not Word (0); asmname 'crt_WindMax';
     
     procedure AssignCRT (var F : Text);
     function  KeyPressed : Boolean; asmname 'crt_keypressed';
     function  ReadKey : Char; asmname 'crt_readkey';
     
     { Not effective on all platforms, see above. See also SetScreenSize
       and SetMonochrome. }
     procedure TextMode (Mode : Integer);
     
     procedure Window (x1, y1, x2, y2 : Integer); asmname 'crt_window';
     procedure GotoXY (x, y : Integer); asmname 'crt_gotoxy';
     function  WhereX : Integer; asmname 'crt_wherex';
     function  WhereY : Integer; asmname 'crt_wherey';
     procedure ClrScr; asmname 'crt_clrscr';
     procedure ClrEOL; asmname 'crt_clreol';
     procedure InsLine; asmname 'crt_insline';
     procedure DelLine; asmname 'crt_delline';
     procedure TextColor (Color : TTextAttr);
     procedure TextBackground (Color : TTextAttr);
     procedure LowVideo;
     procedure HighVideo;
     procedure NormVideo;
     procedure Delay (MS : Word); asmname 'crt_delay';
     
     { Not available on all platforms, see above }
     procedure Sound (Hz : Word); asmname 'crt_sound';
     procedure NoSound; asmname 'crt_nosound';
     
     { =================== Extensions over BP's CRT =================== }
     
     {
       Initializes the CRT unit. Should be called before using any of
       CRT's routines.
     
       Note: For BP compatibility, CRT is initizalized automatically when
       (almost) any of its routines are used for the first time. In this
       case, some defaults are set to match BP more closely. In
       particular, the PC charset (see SetPCCharSet) is enabled then
       (disabled otherwise), and the update level (see SetCRTUpdate) is
       set to UpdateRegularly (UpdateWaitInput otherwise). This feature
       is meant for BP compatibility *only*. Don't rely on it when
       writing a new program. Use CRTInit then, and set the defaults to
       the values you want explicitly.
     
       SetCRTUpdate is one of those few routines which will not cause CRT
       to be initialized immediately, and a value set with it will
       survive both automatic and explicit initialization, so you can use
       it to set the update level without caring which way CRT will be
       initialized. (This does not apply to SetPCCharSet. Since it works
       on a per-panel basis, it has to initialize CRT first, so there is
       a panel to start with.)
     
       If you terminate the program before calling CRTInit or any routine
       that causes automatic initialization, curses will never be
       initialized, so e.g., the screen won't be cleared. This can be
       useful, e.g., to check the command line arguments (or anything
       else) and if there's a problem, write an error and abort. Just be
       sure to write the error to StdErr, not Output (because Output will
       be assigned to CRT, and therefore writing to Output will cause CRT
       to be initialized, and because errors belong to StdErr, anyway),
       and to call `RestoreTerminal (True)' before (just to be sure, in
       case some code -- perhaps added later, or hidden in the
       initialization of some unit -- does initialize CRT).
     }
     procedure CRTInit; asmname 'crt_init';
     
     { Changes the input and output file and the terminal description CRT
       uses. Only effective with ncurses, and only if called before CRT
       is initialized (automatically or explicitly; see the comments for
       CRTInit). If TerminalType is nil, the default will be used. If
       InputFile and/or OutputFile are null, they remain unchanged. }
     procedure CRTSetTerminal (TerminalType : CString; var InputFile,
       OutputFile : AnyFile); asmname 'crt_SetTerminal';
     
     { If called, causes CRT to save the previous screen contents if
       possible (see the comments at the beginning of the unit), and
       restore them when calling RestoreTerminal (True). After
       RestoreTerminal (False), they're saved again, and at the end of
       the program, they're restored. Should be called before
       initializing CRT (using CRTInit or automatically), otherwise the
       previous screen contents may already have been overwritten. Note
       that on some terminals (e.g., xterms and similar), this is the
       default behaviour. Ignored under XCurses, because the program it
       uses its own window, anyway. }
     procedure CRTSavePreviousScreen; asmname 'crt_save_previous_screen';
     
     { Returns True if CRTSavePreviousScreen was called and is available.
       Note that CRTSavePreviousScreenWorks does not work reliably until
       CRT is initialized, while CRTSavePreviousScreen should be called
       before CRT is initialized. That's why they are two separate
       routines. }
     function  CRTSavePreviousScreenWorks : Boolean;
       asmname 'crt_save_previous_screen_works';
     
     { If CRT is initialized automatically, not via CRTInit, and
       CRTAutoInitProc is not nil, it will be called before actually
       initializing CRT. }
     var
       CRTAutoInitProc : procedure = nil; asmname 'crt_auto_init_proc';
     
     { Aborts with a runtime error saying that CRT was not initialized.
       If you set CRTAutoInitProc to this procedure, you can effectively
       disable CRT's automatic initialization. }
     procedure CRTNotInitialized; asmname 'crt_not_initialized';
     
     { Set terminal to shell or curses mode. An internal procedure
       registered by CRT via RegisterRestoreTerminal does this as well,
       so CRTSetCursesMode has to be called only in unusual situations,
       e.g. after executing a process that changes terminal modes, but
       does not restore them (e.g. because it crashed or was killed), and
       the process was not executed with the Execute routine, and
       RestoreTerminal was not called otherwise. If you set it to False
       temporarily, be sure to set it back to True before doing any
       further CRT operations, otherwise the result may be strange. }
     procedure CRTSetCursesMode (On : Boolean);
       asmname 'crt_set_curses_mode';
     
     { Do the same as `RestoreTerminal (True)', but also clear the screen
       after restoring the terminal (except for XCurses, because the
       program uses its own window, anyway). Does not restore and save
       again the previous screen contents if CRTSavePreviousScreen was
       called. }
     procedure RestoreTerminalClearCRT;
       asmname 'crt_RestoreTerminalClearCRT';
     
     { Keyboard and character graphics constants -- BP compatible! =:-}
     {$i crt.inc}
     
     var
       { Tells whether the XCurses version of CRT is used }
       XCRT : Boolean = {$ifdef XCURSES} True {$else} False {$endif};
       asmname 'crt_XCRT';
     
       { If True (default: False), the Beep procedure and writing #7 do a
         Flash instead }
       VisualBell : Boolean = False; asmname 'crt_VisualBell';
     
     type
       TKey = Word;
     
       TCursorShape = (CursorIgnored, CursorHidden, CursorNormal,
       CursorFat, CursorBlock);
     
       TCRTUpdate = (UpdateNever, UpdateWaitInput, UpdateInput,
                     UpdateRegularly, UpdateAlways);
     
       TPoint = record
         X, Y : Integer
       end;
     
       PCharAttr = ^TCharAttr;
       TCharAttr = record
         Ch        : Char;
         Attr      : TTextAttr;
         PCCharSet : Boolean
       end;
     
       PCharAttrs = ^TCharAttrs;
       TCharAttrs = array [1 .. MaxVarSize div SizeOf (TCharAttr)] of
       TCharAttr;
     
       TWindowXY = packed record
         {$ifdef __BYTES_BIG_ENDIAN__}
         Fill : Integer (BitSizeOf (Word) - 16);
         Y, X : Word (8)
         {$else}
         X, Y : Word (8);
         Fill : Integer (BitSizeOf (Word) - 16)
         {$endif}
       end;
     
     { Make sure TWindowXY really has the same size as WindMin and
       WindMax. If not, compilation will abort here with `division by
       zero'. Otherwise, the value of the constant will always be 1, and
       is of no further interest. }
     const
       AssertTWindowXYSize = 1 / Ord ((SizeOf (TWindowXY) = SizeOf
       (WindMin)) and
                                      (SizeOf (TWindowXY) = SizeOf
       (WindMax)));
     
     var
       { Window upper and left coordinates. More comfortable to access
         than WindMin, but also *obsolete*. WindMin and WindowMin still
         work, but have the problem that they implicitly limit the window
         size to 255x255 characters. Though that's not really small for a
         text window, it's easily possible to create bigger ones (e.g. in
         an xterm with a small font, on a high resolution screen and/or
         extending over several virutal desktops). When using coordinates
         greater than 254, the corresponding bytes in WindowMin/WindowMax
         will be set to 254, so, e.g., programs which do
         `Inc (WindowMin.X)' will not fail quite as badly (but probably
         still fail). The routines Window and GetWindow use Integer
         coordinates, and don't suffer from any of these problems, so
         they should be used instead. }
       WindowMin : TWindowXY absolute WindMin;
     
       { Window lower right coordinates. More comfortable to access than
         WindMax, but also *obsolete* (see the comments for WindowMin).
         Use Window and GetWindow instead. }
       WindowMax : TWindowXY absolute WindMax;
     
       { The attribute set by NormVideo }
       NormAttr : TTextAttr = 7; asmname 'crt_NormAttr';
     
       { Tells whether the current mode is monochrome }
       IsMonochrome : Boolean = False; asmname 'crt_IsMonochrome';
     
       { This value can be set to a combination of the shFoo constants
         and will be ORed to the actual shift state returned by
         GetShiftState. This can be used to easily simulate shift keys on
         systems where they can't be accessed. }
       VirtualShiftState : Integer = 0; asmname 'crt_VirtualShiftState';
     
     { Returns the size of the screen. Note: In BP's WinCRT unit,
       ScreenSize is a variable. But since writing to it from a program
       is pointless, anyway, providing a function here should not cause
       any incompatibility. }
     function  ScreenSize : TPoint; asmname 'crt_GetScreenSize';
     
     { Change the screen size if possible. }
     procedure SetScreenSize (x, y : Integer);
       asmname 'crt_SetScreenSize';
     
     { Turns colors off or on. }
     procedure SetMonochrome (Monochrome : Boolean);
       asmname 'crt_SetMonochrome';
     
     { Tell which modifier keys are currently pressed. The result is a
       combination of the shFoo constants defined in crt.inc, or 0 on
       systems where this function is not supported -- but note
       VirtualShiftState. If supported, ReadKey automatically converts
       kbIns and kbDel keys to kbShIns and kbShDel, resp., if shift is
       pressed. }
     function  GetShiftState : Integer; asmname 'crt_getshiftstate';
     
     { Get the extent of the current window. Use this procedure rather
       than reading WindMin and WindMax or WindowMin and WindowMax, since
       this routine allows for window sizes larger than 255. The
       resulting coordinates are 1-based (like in Window, unlike WindMin,
       WindMax, WindowMin and WindowMax). Any of the parameters may be
       null in case you're interested in only some of the coordinates. }
     procedure GetWindow (var x1, y1, x2, y2 : Integer);
       asmname 'crt_getwindow';
     
     {
       Determine when to update the screen. The possible values are the
       following. The given conditions *guarantee* updates. However,
       updates may occur more frequently (even if the update level is set
       to UpdateNever). About the default value, see the comments for
       CRTInit.
     
       UpdateNever     : never (unless explicitly requested with
                         CRTUpdate)
       UpdateWaitInput : before Delay and CRT input, unless typeahead is
                         detected
       UpdateInput     : before Delay and CRT input
       UpdateRegularly : before Delay and CRT input and otherwise in
                         regular intervals without causing too much
                         refresh. This uses a timer on some systems
                         (currently, Unix with ncurses). This was created
                         for BP compatibility, but for many applications,
                         a lower value causes less flickering in the
                         output, and additionally, timer signals won't
                         disturb other operations. Under DJGPP, this
                         always updates immediately, but this fact should
                         not mislead DJGPP users into thinking this is
                         always so.
       UpdateAlways    : after each output. This can be very slow. (Not
                         so under DJGPP, but this fact should not mislead
                         DJGPP users...)
     }
     procedure SetCRTUpdate (UpdateLevel : TCRTUpdate);
       asmname 'crt_setupdatelevel';
     
     { Do an update now, independently of the update level }
     procedure CRTUpdate; asmname 'crt_update_immediately';
     
     { Do an update now and completely redraw the screen }
     procedure CRTRedraw; asmname 'crt_redraw';
     
     { Return Ord (key) for normal keys and $100 * Ord (fkey) for
       function keys }
     function  ReadKeyWord : TKey; asmname 'crt_readkeyword';
     
     { Extract the character and scan code from a TKey value }
     function  Key2Char (k : TKey) : Char;
     function  Key2Scan (k : TKey) : Char;
     
     { Convert a key to upper/lower case if it is a letter, leave it
       unchanged otherwise }
     function  UpCaseKey (k : TKey) : TKey;
     function  LoCaseKey (k : TKey) : TKey;
     
     { Return key codes for the combination of the given key with Ctrl,
       Alt, AltGr or Extra, resp. Returns 0 if the combination is
       unknown. }
     function  CtrlKey  (ch : Char) : TKey; asmname 'crt_ctrlkey';
     function  AltKey   (ch : Char) : TKey; asmname 'crt_altkey';
     function  AltGrKey (ch : Char) : TKey; asmname 'crt_altgrkey';
     function  ExtraKey (ch : Char) : TKey; asmname 'crt_extrakey';
     
     { Check if k is a pseudo key generated by a deadly signal trapped }
     function  IsDeadlySignal (k : TKey) : Boolean;
     
     { Produce a beep or a screen flash }
     procedure Beep; asmname 'crt_beep';
     procedure Flash; asmname 'crt_flash';
     
     { Get size of current window (calculated using GetWindow) }
     function  GetXMax : Integer;
     function  GetYMax : Integer;
     
     { Get/goto an absolute position }
     function  WhereXAbs : Integer;
     function  WhereYAbs : Integer;
     procedure GotoXYAbs (X, Y : Integer);
     
     { Turn scrolling on or off }
     procedure SetScroll (State : Boolean); asmname 'crt_setscroll';
     
     { Read back whether scrolling is enabled }
     function  GetScroll : Boolean; asmname 'crt_getscroll';
     
     { Determine whether to interpret non-ASCII characters as PC ROM
       characters (True), or in a system dependent way (False). About the
       default, see the comments for CRTInit. }
     procedure SetPCCharSet (PCCharSet : Boolean);
       asmname 'crt_setpccharset';
     
     { Read back the value set by SetPCCharSet }
     function  GetPCCharSet : Boolean; asmname 'crt_getpccharset';
     
     { Determine whether to interpret #7, #8, #10, #13 as control
       characters (True, default), or as graphics characters (False) }
     procedure SetControlChars (UseControlChars : Boolean);
       asmname 'crt_setcontrolchars';
     
     { Read back the value set by SetControlChars }
     function  GetControlChars : Boolean; asmname 'crt_getcontrolchars';
     
     procedure SetCursorShape (Shape : TCursorShape);
       asmname 'crt_setcursorshape';
     function  GetCursorShape : TCursorShape;
       asmname 'crt_getcursorshape';
     
     procedure HideCursor;
     procedure HiddenCursor;
     procedure NormalCursor;
     procedure FatCursor;
     procedure BlockCursor;
     procedure IgnoreCursor;
     
     { Simulates a block cursor by writing a block character onto the
       cursor position. The procedure automatically finds the topmost
       visible panel whose shape is not CursorIgnored and places the
       simulated cursor there (just like the hardware cursor), with
       matching attributes, if the cursor shape is CursorFat or
       CursorBlock (otherwise, no simulated cursor is shown).
     
       Calling this procedure again makes the simulated cursor disappear.
       In particular, to get the effect of a blinking cursor, you have to
       call the procedure repeatedly (say, 8 times a second). CRT will
       not do this for you, since it does not intend to be your main
       event loop. }
     procedure SimulateBlockCursor; asmname 'crt_SimulateBlockCursor';
     
     { Makes the cursor simulated by SimulateBlockCursor disappear if it
       is active. Does nothing otherwise. You should call this procedure
       after using SimulateBlockCursor before doing any further CRT
       output (though failing to do so should not hurt except for
       possibly leaving the simulated cursor in its old position longer
       than it should). }
     procedure SimulateBlockCursorOff;
       asmname 'crt_SimulateBlockCursorOff';
     
     function  GetTextColor : Integer;
     function  GetTextBackground : Integer;
     
     { Write string at the given position without moving the cursor.
       Truncated at the right margin. }
     procedure WriteStrAt (x, y : Integer; s : String; Attr : TTextAttr);
     
     { Write (several copies of) a char at then given position without
       moving the cursor. Truncated at the right margin. }
     procedure WriteCharAt (x, y, Count : Integer; Ch : Char; Attr :
       TTextAttr);
     
     { Write characters with specified attributes at the given position
       without moving the cursor. Truncated at the right margin. }
     procedure WriteCharAttrAt (x, y, Count : Integer; CharAttr :
       PCharAttrs); asmname 'crt_writecharattrat';
     
     { Write a char while moving the cursor }
     procedure WriteChar (Ch : Char);
     
     { Read a character from a screen position }
     procedure ReadChar (x, y : Integer; var Ch : Char; var Attr :
       TTextAttr); asmname 'crt_readchar';
     
     { Change only text attributes, leave characters. Truncated at the
       right margin. }
     procedure ChangeTextAttr (x, y, Count : Integer; NewAttr :
       TTextAttr);
     
     { Fill current window }
     procedure FillWin (Ch : Char; Attr : TTextAttr);
       asmname 'crt_fillwin';
     
     { Calculate size of memory required for ReadWin in current window. }
     function  WinSize : SizeType; asmname 'crt_winsize';
     
     { Save window contents. Buf must be WinSize bytes large. }
     procedure ReadWin (var Buf); asmname 'crt_readwin';
     
     { Restore window contents saved by ReadWin. The size of the current
       window must match the size of the window from which ReadWin was
       used, but the position may be different. }
     procedure WriteWin (const Buf); asmname 'crt_writewin';
     
     type
       WinState = record
         x1, y1, x2, y2, WhereX, WhereY, NewX1, NewY1, NewX2, NewY2 :
       Integer;
         TextAttr : TTextAttr;
         CursorShape : TCursorShape;
         ScreenSize : TPoint;
         Buffer : ^Byte
       end;
     
     { Save window position and size, cursor position, text attribute and
       cursor shape -- *not* the window contents. }
     procedure SaveWin (var State : WinState);
     
     { Make a new window (like Window), and save the contents of the
       screen below the window as well as the position and size, cursor
       position, text attribute and cursor shape of the old window. }
     procedure MakeWin (var State : WinState; x1, y1, x2, y2 : Integer);
     
     { Create window in full size, save previous text mode and all values
       that MakeWin does. }
     procedure SaveScreen (var State : WinState);
     
     { Restore the data saved by SaveWin, MakeWin or SaveScreen. }
     procedure RestoreWin (var State : WinState);
     
     { Panels }
     
     type
       TPanel = Pointer;
     
     function  GetActivePanel : TPanel; asmname 'crt_GetActivePanel';
     procedure PanelNew                 (x1, y1, x2, y2 : Integer;
       BindToBackground : Boolean); asmname 'crt_PanelNew';
     procedure PanelDelete              (Panel : TPanel);
       asmname 'crt_PanelDelete';
     procedure PanelBindToBackground    (Panel : TPanel; Bind : Boolean);
       asmname 'crt_PanelBindToBackground';
     function  PanelIsBoundToBackground (Panel : TPanel) : Boolean;
       asmname 'crt_PanelIsBoundToBackground';
     procedure PanelActivate            (Panel : TPanel);
       asmname 'crt_PanelActivate';
     procedure PanelHide                (Panel : TPanel);
       asmname 'crt_PanelHide';
     procedure PanelShow                (Panel : TPanel);
       asmname 'crt_PanelShow';
     function  PanelHidden              (Panel : TPanel) : Boolean;
       asmname 'crt_PanelHidden';
     procedure PanelTop                 (Panel : TPanel);
       asmname 'crt_PanelTop';
     procedure PanelBottom              (Panel : TPanel);
       asmname 'crt_PanelBottom';
     procedure PanelMoveAbove           (Panel, Above : TPanel);
       asmname 'crt_PanelMoveAbove';
     procedure PanelMoveBelow           (Panel, Below : TPanel);
       asmname 'crt_PanelMoveBelow';
     function  PanelAbove               (Panel : TPanel) : TPanel;
       asmname 'crt_PanelAbove';
     function  PanelBelow               (Panel : TPanel) : TPanel;
       asmname 'crt_PanelBelow';
     
     { TPCRT compatibility }
     
     { Write a string at the given position without moving the cursor.
       Truncated at the right margin. }
     procedure WriteString (const s : String; y, x : Integer);
     
     { Write a string at the given position with the given attribute
       without moving the cursor. Truncated at the right margin. }
     procedure FastWriteWindow (const s : String; y, x : Integer; Attr :
       TTextAttr);
     
     { Write a string at the given absolute position with the given
       attribute without moving the cursor. Truncated at the right
       margin. }
     procedure FastWrite       (const s : String; y, x : Integer; Attr :
       TTextAttr);
     
     { WinCrt compatibility }
     
     const
       cw_UseDefault = Integer ($8000);
     
     var
       WindowOrg  : TPoint = (cw_UseDefault, cw_UseDefault); { Ignored }
       WindowSize : TPoint = (cw_UseDefault, cw_UseDefault); { Ignored }
       Cursor     : TPoint = (0, 0); { Cursor location, 0-based }
       asmname 'crt_cursor_pos';
       Origin     : TPoint = (0, 0); { Ignored }
       InactiveTitle : PChar = '(Inactive %s)'; { Ignored }
       AutoTracking : Boolean = True; { Ignored }
       WindowTitle : {$ifdef __BP_TYPE_SIZES__}
                     array [0 .. 79] of Char
                     {$else}
                     TStringBuf
                     {$endif}; { CRT window title, ignored }
     
     procedure InitWinCrt; asmname 'crt_initwincrt';
     
     { Halts the program }
     procedure DoneWinCrt; attribute (noreturn);
       asmname 'crt_donewincrt';
     
     procedure WriteBuf (Buffer : PChar; Count : SizeType);
       asmname 'crt_writebuf';
     
     function  ReadBuf (Buffer : PChar; Count : SizeType) : SizeType;
       asmname 'crt_readbuf';
     
     { 0-based coordinates! }
     procedure CursorTo (x, y : Integer); asmname 'crt_cursorto';
     
     { Dummy }
     procedure ScrollTo (x, y : Integer); asmname 'crt_scrollto';
     
     { Dummy }
     procedure TrackCursor; asmname 'crt_trackcursor';


File: gpc,  Node: Dos,  Next: DosUnix,  Prev: CRT,  Up: GPC Units

7.13.2 BP compatibility: Dos
----------------------------

   The following listing contains the interface of the Dos unit.

   This is a portable implementation of most routines from BP's `Dos'
unit. A few routines that are Dos - or even x86 real mode - specific,
are only available if `__BP_UNPORTABLE_ROUTINES__' is defined, *Note BP
Incompatibilities::.

   The same functionality and much more is available in the Run Time
System, *Note Run Time System::. In some cases, the RTS routines have
the same interface as the routines in this unit (e.g.  `GetEnv',
`FSplit', `FExpand', `FSearch'), in other cases, they have different
names and/or easier and less limiting interfaces (e.g. `ReadDir' etc.
vs. `FindFirst' etc.), and are often more efficient.

   Therefore, using this unit is not recommended in newly written
programs.

     {
     Portable BP compatible Dos unit
     
     This unit supports most of the routines and declarations of BP's Dos
     unit.
     
     NOTES:
     
     - The procedures Keep, GetIntVec, SetIntVec are not supported since
       they make only sense for Dos real-mode programs (and GPC compiled
       programs do not run in real-mode, even on x86 under Dos). The
       procedures Intr and MsDos are only supported under DJGPP if
       `__BP_UNPORTABLE_ROUTINES__' is defined (with the
       `-D__BP_UNPORTABLE_ROUTINES__' option). A few other routines are
       also only supported with this define, but on all platforms (but
       they are crude hacks, that's why they are not supported without
       this define).
     
     - The internal structure of file variables (FileRec and TextRec) is
       different in GPC. However, as far as TFDDs are concerned, there
       are other ways to achieve the same in GPC, see the GPC unit.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Authors: Frank Heckenbach <frank@pascal.gnu.de>
              Prof. Abimbola A. Olowofoyeku <African_Chief@bigfoot.com>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit Dos;
     
     interface
     
     uses GPC, System;
     
     type
       Byte8 = Cardinal (8);
       TDosAttr = Word;
       GPC_AnyFile = AnyFile; { in order to have AnyFile parameters,
                                while AnyFile is redefined below }
     
     const
       { File attribute constants }
       ReadOnly      = $01;
       Hidden        = $02; { set for dot files except '.' and '..' }
       SysFile       = $04; { not supported }
       VolumeID      = $08; { not supported }
       Directory     = $10;
       Archive       = $20; { means: not executable }
       {$local W-} AnyFile = $3f; {$endlocal}
     
       { Flag bit masks -- only used by the unportable Dos routines }
       FCarry     = 1;
       FParity    = 4;
       FAuxiliary = $10;
       FZero      = $40;
       FSign      = $80;
       FOverflow  = $800;
     
       { DosError codes }
       DosError_FileNotFound = 2;
       DosError_PathNotFound = 3;
       DosError_AccessDenied = 5;
       DosError_InvalidMem   = 9;
       DosErorr_InvalidEnv   = 10;
       DosError_NoMoreFiles  = 18;
       DosError_IOError      = 29;
       DosError_ReadFault    = 30;
     
     type
       { String types. Not used in this unit, but declared for
         compatibility. }
       ComStr  = String [127];        { Command line string }
       PathStr = String [79];         { File pathname string }
       DirStr  = String [67];         { Drive and directory string }
       NameStr = String [8];          { File name string }
       ExtStr  = String [4];          { File extension string }
     
       TextBuf = array [0 .. 127] of Char;
     
       { Search record used by FindFirst and FindNext }
       SearchRecFill = packed array [1 .. 21] of Byte8;
       SearchRec = {$ifdef __BP_TYPE_SIZES__} packed {$endif} record
         Fill : SearchRecFill;
         Attr : Byte8;
         Time, Size : LongInt;
         Name : {$ifdef __BP_TYPE_SIZES__}
                String [12]
                {$else}
                TString
                {$endif}
       end;
     
       { Date and time record used by PackTime and UnpackTime }
       DateTime = record
         Year, Month, Day, Hour, Min, Sec : Word
       end;
     
       { 8086 CPU registers -- only used by the unportable Dos routines }
       Registers = record
       case Boolean of
         False : (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Word16);
         True  : (AL, AH, BL, BH, CL, CH, DL, DH : Byte8)
       end;
     
     var
       { Error status variable }
       DosError : Integer = 0;
     
     procedure GetDate (var Year, Month, Day, DayOfWeek : Word);
       asmname '_p_getdate';
     procedure GetTime (var Hour, Minute, Second, Sec100 : Word);
       asmname '_p_gettime';
     procedure GetCBreak (var BreakOn : Boolean); asmname '_p_getcbreak';
     procedure SetCBreak (BreakOn : Boolean); asmname '_p_setcbreak';
     { GetVerify and SetVerify are dummies except for DJGPP (in the
       assumption that any real OS knows by itself when and how to verify
       its disks). }
     procedure GetVerify (var VerifyOn : Boolean);
       asmname '_p_getverify';
     procedure SetVerify (VerifyOn : Boolean); asmname '_p_setverify';
     function  DiskFree (Drive : Byte) : LongInt; asmname '_p_diskfree';
     function  DiskSize (Drive : Byte) : LongInt; asmname '_p_disksize';
     procedure GetFAttr (var F : GPC_AnyFile; var Attr : TDosAttr);
       asmname '_p_getfattr';
     procedure SetFAttr (var F : GPC_AnyFile; Attr : TDosAttr);
       asmname '_p_setfattr';
     procedure GetFTime (var F : GPC_AnyFile; var aTime : LongInt);
       asmname '_p_getftime';
     procedure SetFTime (var F : GPC_AnyFile; aTime : LongInt);
       asmname '_p_setftime';
     
     { FindFirst and FindNext are quite inefficient since they emulate
       all the brain-dead Dos stuff. If at all possible, the standard
       routines OpenDir, ReadDir and CloseDir (in the GPC unit) should be
       used instead. }
     procedure FindFirst (const Path : String; Attr : TDosAttr; var SR :
       SearchRec); asmname '_p_findfirst';
     procedure FindNext  (var SR : SearchRec); asmname '_p_findnext';
     
     procedure FindClose (var SR : SearchRec); asmname '_p_findclose';
     procedure UnpackTime (P : LongInt; var T : DateTime);
       asmname '_p_unpacktime';
     procedure PackTime (const T : DateTime; var P : LongInt);
       asmname '_p_packtime';
     function  FSearch (const aFileName, DirList : String) : TString;
       asmname '_p_fsearch';
     function  FExpand (const Path : String) : TString;
       asmname '_p_fexpand';
     procedure FSplit  (const Path : String; var Dir, Name, Ext :
       String); asmname '_p_fsplit';
     function  EnvCount : Integer;
     function  EnvStr (EnvIndex : Integer) : TString;
     function  GetEnv (const EnvVar : String) : TString;
       asmname '_p_getenv';
     procedure SwapVectors;
     { Exec executes a process via Execute, so RestoreTerminal is called
       with
       the argument True before and False after executing the process. }
     procedure Exec (const Path, Params : String);
     function  DosExitCode : Word;
     
     { Unportable Dos-only routines and declarations }
     
     {$ifdef __BP_UNPORTABLE_ROUTINES__}
     {$ifdef DJGPP}
     { These are unportable Dos-only declarations and routines, since
       interrupts are Dos and CPU specific (and have no place in a
       high-level program, anyway). }
     procedure Intr (IntNo : Byte; var Regs : Registers);
       asmname '_p_intr';
     procedure MsDos (var Regs : Registers); asmname '_p_msdos';
     {$endif}
     
     { Though probably all non-Dos system have versions numbers as well,
       returning them here would usually not do what is expected, e.g.
       testing if certain Dos features are present by comparing the
       version number. Therefore, this routine always returns 7 (i.e.,
       version 7.0) on non-Dos systems, in the assumption that any real
       OS has at least the features of Dos 7. }
     function  DosVersion : Word; asmname '_p_dosversion';
     
     { Changing the system date and time is a system administration task,
       not allowed to a normal process. On non-Dos systems, these
       routines emulate the changed date/time, but only for GetTime and
       GetDate (not the RTS date/time routines), and only for this
       process, not for child processes or even the parent process or
       system-wide. }
     procedure SetDate (Year, Month, Day : Word); asmname '_p_setdate';
     procedure SetTime (Hour, Minute, Second, Sec100 : Word);
       asmname '_p_settime';
     {$endif}


File: gpc,  Node: DosUnix,  Next: FileUtils,  Prev: Dos,  Up: GPC Units

7.13.3 Overcome some differences between Dos and Unix
-----------------------------------------------------

   The following listing contains the interface of the DosUnix unit.

   This unit is there to overcome some of those differences between Dos
and Unix systems that are not automatically hidden by GPC and the Run
Time System. Currently features translation of bash style input/output
redirections (`foo 2>&1') into `redir' calls for DJGPP (`redir -eo
foo') and a way to read files with Dos CR/LF pairs on any system.

   When necessary, new features will be added to the unit in future
releases.

     {
     Some routines to support writing programs portable between Dos and
     Unix. Perhaps it would be a good idea not to put features to make
     Dos programs Unix-compatible (shell redirections) and vice versa
     (reading Dos files from Unix) together into one unit, but rather
     into two units, DosCompat and UnixCompat or so -- let's wait and
     see, perhaps when more routines suited for this/these unit(s) will
     be found, the design will become clearer...
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit DosUnix;
     
     interface
     
     uses GPC;
     
     {
       This function is meant to be used when you want to invoke a system
       shell command (e.g. via Execute or Exec from the Dos unit) and
       want to specify input/output redirections for the command invoked.
       It caters for the different syntax between DJGPP (with the `redir'
       utility) and other systems.
     
       To use it, code your redirections in bash style (see the table
       below) in your command line string, pass this string to this
       function, and the function's result to Execute or the other
       routines.
     
       The function translates the following bash style redirections
       (characters in brackets are optional) into a redir call under Dos
       systems except EMX, and leave them unchanged under other systems.
       Note: `redir' comes with DJGPP, but it should be possible to
       install it on other Dos systems as well. OS/2's shell, however,
       supports bash style redirections, I was told, so we don't
       translate on EMX.
     
       [0]<     file      redirect standard input from file
       [1]>[|]  file      redirect standard output to file
       [1]>>    file      append standard output to file
       [1]>&2             redirect standard output to standard error
       2>[|]    file      redirect standard error to file
       2>>      file      append standard error to file
       2>&1               redirect standard error to standard output
       &> file            redirect both standard output and standard
                          error to file
     }
     function TranslateRedirections (const Command : String) : TString;
     
     { Under Unix, translates CR/LF pairs to single LF characters when
       reading from f, and back when writing to f. Under Dos, does
       nothing because the run time system alrady does this job. In the
       result, you can read both Dos and Unix files, and files written
       will be Dos. }
     procedure AssignDos (var f : AnyFile; const Name : String);


File: gpc,  Node: FileUtils,  Next: GMP,  Prev: DosUnix,  Up: GPC Units

7.13.4 Higher level file and directory handling
-----------------------------------------------

   The following listing contains the interface of the FileUtils unit.

   This unit provides some routines for file and directory handling on
a higher level than those provided by the RTS.

     {
     Some routines for file and directory handling on a higher level than
     those provided by the RTS.
     
     Copyright (C) 2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit FileUtils;
     
     interface
     
     uses GPC;
     
     type
       TStringProc = procedure (const Name : String);
     
     {
       Finds all files matching the given Mask in the given Directory and
       all subdirectories of it. The matching is done using all wildcards
       and brace expansion, like MultiFileNameMatch does. For each file
       found, FileAction is executed. For each directory found (including
       `.' and `..' if they match the Mask!), DirAction is executed. If
       MainDirFirst is True, this happens before processing the files in
       the directory and below, otherwise afterwards. (The former is
       useful, e.g., if this is used to copy a directory tree and
       DirAction does a MkDir, while the latter behaviour is required
       when removing a directory tree and DirAction does a RmDir.) Both
       FileAction and DirAction can be nil in which case nothing is done
       for files or directories found, respectively. (If DirAction is
       nil, the value of DirsFirst does not matter.) Of course,
       FileAction and DirAction may also be identical. The procedure
       leaves InOutRes set in case of any error. If FileAction or
       DirAction return with InOutRes set, FindFiles recognizes this and
       returns immediately.
     }
     (*@@iocritical*)procedure FindFiles (const Directory, Mask : String;
       MainDirFirst : Boolean;
                          FileAction, DirAction : TStringProc);
       asmname '_p_findfiles';
     
     {
       Creates the directory given by Path and all directories in between
       that are necessary. Does not report an error if Path already
       exists and is a directory, but, of course, if it cannot be created
       because of missing permissions or because Path already exists as a
       file.
     }
     (*@@iocritical*)procedure MkDirs (const Path : String);
       asmname '_p_mkdirs';
     
     {
       Removes Path if empty as well as any empty parent directories.
       Does not report an error if Path is not empty.
     }
     (*@@iocritical*)procedure RmDirs (const Path : String);
       asmname '_p_rmdirs';
     
     {
       Copies the file Source to Dest, overwriting Dest if it exists and
       can be written to. Returns any errors in IOResult. If Mode >= 0,
       it will change the permissions of Dest to Mode immediately after
       creating it and before writing any data to it. That's useful,
       e.g., if Dest is not meant to be world-readable, because if you'd
       do a ChMod after FileCopy, you would leave the data readable
       (depending on the umask) during the copying. If Mode < 0, Dest
       will be set to the same permissions Source has. In any case, Dest
       will be set to the modification time of Source after coyping.
     }
     (*@@iocritical*)procedure FileCopy (const Source, Dest : String;
       Mode : Integer); asmname '_p_filecopy';
     
     {
       Creates a backup of FileName in the directory BackupDirectory or,
       if BackupDirectory is empty, in the directory of FileName. Errors
       are returned in IOResult, but if FileName does not exist, this
       does *not* count as an error (i.e., BackupFile will just return
       without setting IOResult then). If OnlyUserReadable is True, the
       backup file will be given only user-read permissions, nothing
       else.
     
       The name chosen for the backup depends on the Simple and Short
       parameters. The short names will fit into 8+3 characters (whenever
       possible), while the long ones conform to the conventions used by
       most GNU tools. If Simple is True, a simple backup file name will
       be used, and previous backups under the same name will be
       overwritten (if possible). Otherwise, backups will be numbered,
       where the number is chosen to be larger than all existing backups,
       so it will be unique and increasing in chronological order. In
       particular:
     
       Simple  Short  Backup name
       True    True   Base name of FileName plus '.bak'
       False   True   Base name of FileName plus '.b' plus a number
       True    False  Base name plus extension of FileName plus '~'
       False   False  Base name plus extension of FileName plus '.~', a
                      number and '~'
     }
     (*@@iocritical*)procedure BackupFile (const FileName,
       BackupDirectory : String; Simple, Short, OnlyUserReadable :
       Boolean); asmname '_p_backupfile';


File: gpc,  Node: GMP,  Next: GPCUtil,  Prev: FileUtils,  Up: GPC Units

7.13.5 Arithmetic with unlimited size and precision
---------------------------------------------------

   The following listing contains the interface of the GMP unit.

   This unit provides an interface to the GNU Multiprecision Library to
perform arithmetic on integer, rational and real numbers of unlimited
size and precision.

   To use this unit, you will need the `gmp' library which can be found
in `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/'.

     {
     Definitions for GNU multiple precision functions: arithmetic with
     integer, rational and real numbers of arbitrary size and precision.
     
     Translation of the C header (gmp.h) of the GMP library. Tested with
     GMP 2.0.2 and 3.0.1.
     
     To use the GMP unit, you will need the GMP library which can be
     found in ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/ .
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     
     Please also note the license of the GMP library.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     {$nested-comments}
     
     { If this define is set, routines new in GMP 3.x will be made
       available. The define will have no effect on the other interface
       changes between GMP 2.x and 3.x, i.e. the other routines will work
       correctly even if this define is set incorrectly, except on 64 bit
       machines, Crays and other systems where the types are different
       between the GMP versions. Otherwise, the only possible problem if
       setting the define while using GMP 2.x are linking errors if you
       actually use any of the new routines. }
     {$ifndef HAVE_GMP2}
     {$define HAVE_GMP3}
     {$endif}
     
     unit gmp;
     
     interface
     
     uses GPC;
     
     {$if defined (__mips) && defined (_ABIN32) && defined (HAVE_GMP3)}
     { Force the use of 64-bit limbs for all 64-bit MIPS CPUs if ABI
       permits. }
     {$define _LONG_LONG_LIMB}
     {$endif}
     
     type
       {$ifdef _SHORT_LIMB}
       mp_limb_t        = Cardinal;
       mp_limb_signed_t = Integer;
       {$elif defined(_LONG_LONG_LIMB)}
       mp_limb_t        = LongCard;
       mp_limb_signed_t = LongInt;
       {$else}
       mp_limb_t        = MedCard;
       mp_limb_signed_t = MedInt;
       {$endif}
     
       mp_ptr           = ^mp_limb_t;
     
       {$if defined (_CRAY) && !defined (_CRAYMPP) && defined
       (HAVE_GMP3)}
       mp_size_t        = Integer;
       mp_exp_t         = Integer;
       {$else}
       mp_size_t        = MedInt;
       mp_exp_t         = MedInt;
       {$endif}
     
       mpz_t = record
         mp_alloc,
         mp_size  : {$if defined(__MP_SMALL__) && defined (HAVE_GMP3)}
                    ShortInt
                    {$else}
                    Integer
                    {$endif};
         mp_d     : mp_ptr
       end;
     
       mpz_array_ptr = ^mpz_array;
       mpz_array = array [0 .. MaxVarSize div SizeOf (mpz_t)] of mpz_t;
     
       mpq_t = record
         mp_num,
         mp_den : mpz_t
       end;
     
       mpf_t = record
         mp_prec,
         mp_size : Integer;
         mp_exp  : mp_exp_t;
         mp_d    : mp_ptr
       end;
     
       TAllocFunction    = function (Size : SizeType) : Pointer;
       TReAllocFunction  = function (var Dest : Pointer; OldSize,
       NewSize : SizeType) : Pointer;
       TDeAllocProcedure = procedure (Src : Pointer; Size : SizeType);
     
     procedure mp_set_memory_functions (AllocFunction : TAllocFunction;
                                        ReAllocFunction :
       TReAllocFunction;
                                        DeAllocProcedure :
       TDeAllocProcedure); asmname '__gmp_set_memory_functions';
     
     function mp_bits_per_limb : Integer; asmname '_p_mp_bits_per_limb';
     
     {**************** Integer (i.e. Z) routines.  ****************}
     
     procedure mpz_init             (var Dest : mpz_t);
       asmname '__gmpz_init';
     procedure mpz_clear            (var Dest : mpz_t);
       asmname '__gmpz_clear';
     function  mpz_realloc          (var Dest : mpz_t; NewAlloc :
       mp_size_t) : Pointer; asmname '__gmpz_realloc';
     procedure mpz_array_init       (Dest : mpz_array_ptr; ArraySize,
       FixedNumBits : mp_size_t); asmname '__gmpz_array_init';
     
     procedure mpz_set              (var Dest : mpz_t; protected var
       Src : mpz_t); asmname '__gmpz_set';
     procedure mpz_set_ui           (var Dest : mpz_t; Src : MedCard);
       asmname '__gmpz_set_ui';
     procedure mpz_set_si           (var Dest : mpz_t; Src : MedInt);
       asmname '__gmpz_set_si';
     procedure mpz_set_d            (var Dest : mpz_t; Src : Double);
       asmname '__gmpz_set_d';
     procedure mpz_set_q            (var Dest : mpz_t; Src : mpq_t);
       asmname '__gmpz_set_q';
     procedure mpz_set_f            (var Dest : mpz_t; Src : mpf_t);
       asmname '__gmpz_set_f';
     function  mpz_set_str          (var Dest : mpz_t; Src : CString;
       Base : Integer) : Integer; asmname '__gmpz_set_str';
     
     procedure mpz_init_set         (var Dest : mpz_t; protected var
       Src : mpz_t); asmname '__gmpz_init_set';
     procedure mpz_init_set_ui      (var Dest : mpz_t; Src : MedCard);
       asmname '__gmpz_init_set_ui';
     procedure mpz_init_set_si      (var Dest : mpz_t; Src : MedInt);
       asmname '__gmpz_init_set_si';
     procedure mpz_init_set_d       (var Dest : mpz_t; Src : Double);
       asmname '__gmpz_init_set_d';
     function  mpz_init_set_str     (var Dest : mpz_t; Src : CString;
       Base : Integer) : Integer; asmname '__gmpz_init_set_str';
     
     function  mpz_get_ui           (protected var Src : mpz_t) :
       MedCard; asmname '__gmpz_get_ui';
     function  mpz_get_si           (protected var Src : mpz_t) : MedInt;
       asmname '__gmpz_get_si';
     function  mpz_get_d            (protected var Src : mpz_t) : Double;
       asmname '__gmpz_get_d';
     { Pass nil for Dest to let the function allocate memory for it }
     function  mpz_get_str          (Dest : CString; Base : Integer;
       protected var Src : mpz_t) : CString; asmname '__gmpz_get_str';
     
     procedure mpz_add              (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_add';
     procedure mpz_add_ui           (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_add_ui';
     procedure mpz_sub              (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_sub';
     procedure mpz_sub_ui           (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_sub_ui';
     procedure mpz_mul              (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_mul';
     procedure mpz_mul_ui           (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_mul_ui';
     procedure mpz_mul_2exp         (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_mul_2exp';
     procedure mpz_neg              (var Dest : mpz_t; protected var
       Src : mpz_t); asmname '__gmpz_neg';
     procedure mpz_abs              (var Dest : mpz_t; protected var
       Src : mpz_t); asmname '__gmpz_abs';
     procedure mpz_fac_ui           (var Dest : mpz_t; Src : MedCard);
       asmname '__gmpz_fac_ui';
     
     procedure mpz_tdiv_q           (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_tdiv_q';
     procedure mpz_tdiv_q_ui        (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_q_ui';
     procedure mpz_tdiv_r           (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_tdiv_r';
     procedure mpz_tdiv_r_ui        (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_r_ui';
     procedure mpz_tdiv_qr          (var DestQ, DestR : mpz_t; protected
       var Src1, Src2 : mpz_t); asmname '__gmpz_tdiv_qr';
     procedure mpz_tdiv_qr_ui       (var DestQ, DestR : mpz_t; protected
       var Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_qr_ui';
     
     procedure mpz_fdiv_q           (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_fdiv_q';
     function  mpz_fdiv_q_ui        (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard) : MedCard;
       asmname '__gmpz_fdiv_q_ui';
     procedure mpz_fdiv_r           (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_fdiv_r';
     function  mpz_fdiv_r_ui        (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard) : MedCard;
       asmname '__gmpz_fdiv_r_ui';
     procedure mpz_fdiv_qr          (var DestQ, DestR : mpz_t; protected
       var Src1, Src2 : mpz_t); asmname '__gmpz_fdiv_qr';
     function  mpz_fdiv_qr_ui       (var DestQ, DestR : mpz_t; protected
       var Src1 : mpz_t; Src2 : MedCard) : MedCard;
       asmname '__gmpz_fdiv_qr_ui';
     function  mpz_fdiv_ui          (protected var Src1 : mpz_t; Src2 :
       MedCard) : MedCard; asmname '__gmpz_fdiv_ui';
     
     procedure mpz_cdiv_q           (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_cdiv_q';
     function  mpz_cdiv_q_ui        (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard) : MedCard;
       asmname '__gmpz_cdiv_q_ui';
     procedure mpz_cdiv_r           (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_cdiv_r';
     function  mpz_cdiv_r_ui        (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard) : MedCard;
       asmname '__gmpz_cdiv_r_ui';
     procedure mpz_cdiv_qr          (var DestQ, DestR : mpz_t; protected
       var Src1,Src2 : mpz_t); asmname '__gmpz_cdiv_qr';
     function  mpz_cdiv_qr_ui       (var DestQ, DestR : mpz_t; protected
       var Src1 : mpz_t; Src2 : MedCard) : MedCard;
       asmname '__gmpz_cdiv_qr_ui';
     function  mpz_cdiv_ui          (protected var Src1 : mpz_t;
       Src2:MedCard) : MedCard; asmname '__gmpz_cdiv_ui';
     
     procedure mpz_mod              (var Dest : mpz_t; protected var
       Src1,Src2 : mpz_t); asmname '__gmpz_mod';
     procedure mpz_divexact         (var Dest : mpz_t; protected var
       Src1,Src2 : mpz_t); asmname '__gmpz_divexact';
     
     procedure mpz_tdiv_q_2exp      (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_q_2exp';
     procedure mpz_tdiv_r_2exp      (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_tdiv_r_2exp';
     procedure mpz_fdiv_q_2exp      (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_fdiv_q_2exp';
     procedure mpz_fdiv_r_2exp      (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_fdiv_r_2exp';
     
     procedure mpz_powm             (var Dest : mpz_t; protected var
       Base, Exponent, Modulus : mpz_t); asmname '__gmpz_powm';
     procedure mpz_powm_ui          (var Dest : mpz_t; protected var
       Base : mpz_t; Exponent : MedCard; protected var Modulus : mpz_t);
       asmname '__gmpz_powm_ui';
     procedure mpz_pow_ui           (var Dest : mpz_t; protected var
       Base : mpz_t; Exponent : MedCard); asmname '__gmpz_pow_ui';
     procedure mpz_ui_pow_ui        (var Dest : mpz_t; Base, Exponent :
       MedCard); asmname '__gmpz_ui_pow_ui';
     
     procedure mpz_sqrt             (var Dest : mpz_t; protected var
       Src : mpz_t); asmname '__gmpz_sqrt';
     procedure mpz_sqrtrem          (var Dest, DestR : mpz_t; protected
       var Src : mpz_t); asmname '__gmpz_sqrtrem';
     function  mpz_perfect_square_p (protected var Src : mpz_t) :
       Integer; asmname '__gmpz_perfect_square_p';
     
     function  mpz_probab_prime_p   (protected var Src : mpz_t;
       Repetitions : Integer) : Integer; asmname '__gmpz_probab_prime_p';
     procedure mpz_gcd              (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_gcd';
     function  mpz_gcd_ui           (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard) : MedCard; asmname '__gmpz_gcd_ui';
     procedure mpz_gcdext           (var Dest, DestA, DestB : mpz_t;
       protected var SrcA, SrcB : mpz_t); asmname '__gmpz_gcdext';
     function  mpz_invert           (var Dest : mpz_t; protected var Src,
       Modulus : mpz_t) : Integer; asmname '__gmpz_invert';
     function  mpz_jacobi           (protected var Src1, Src2 : mpz_t) :
       Integer; asmname '__gmpz_jacobi';
     function  mpz_legendre         (protected var Src1, Src2 : mpz_t) :
       Integer; asmname '__gmpz_legendre';
     
     function  mpz_cmp              (protected var Src1, Src2 : mpz_t) :
       Integer; asmname '__gmpz_cmp';
     function  mpz_cmp_ui           (protected var Src1 : mpz_t; Src2 :
       MedCard) : Integer; asmname '__gmpz_cmp_ui';
     function  mpz_cmp_si           (protected var Src1 : mpz_t; Src2 :
       MedInt) : Integer; asmname '__gmpz_cmp_si';
     function  mpz_sgn              (protected var Src : mpz_t) :
       Integer;
     
     procedure mpz_and              (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_and';
     procedure mpz_ior              (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_ior';
     procedure mpz_com              (var Dest : mpz_t; protected var
       Src : mpz_t); asmname '__gmpz_com';
     function  mpz_popcount         (protected var Src : mpz_t) :
       MedCard; asmname '__gmpz_popcount';
     function  mpz_hamdist          (protected var Src1, Src2 : mpz_t) :
       MedCard; asmname '__gmpz_hamdist';
     function  mpz_scan0            (protected var Src : mpz_t;
       StartingBit : MedCard) : MedCard; asmname '__gmpz_scan0';
     function  mpz_scan1            (protected var Src : mpz_t;
       StartingBit : MedCard) : MedCard; asmname '__gmpz_scan1';
     procedure mpz_setbit           (var Dest : mpz_t; BitIndex :
       MedCard); asmname '__gmpz_setbit';
     procedure mpz_clrbit           (var Dest : mpz_t; BitIndex :
       MedCard); asmname '__gmpz_clrbit';
     
     procedure mpz_random           (var Dest : mpz_t; MaxSize :
       mp_size_t); asmname '__gmpz_random';
     procedure mpz_random2          (var Dest : mpz_t; MaxSize :
       mp_size_t); asmname '__gmpz_random2';
     function  mpz_sizeinbase       (protected var Src : mpz_t; Base :
       Integer) : SizeType; asmname '__gmpz_sizeinbase';
     
     {**************** Rational (i.e. Q) routines.  ****************}
     
     procedure mpq_canonicalize     (var Dest : mpq_t);
       asmname '__gmpq_canonicalize';
     
     procedure mpq_init             (var Dest : mpq_t);
       asmname '__gmpq_init';
     procedure mpq_clear            (var Dest : mpq_t);
       asmname '__gmpq_clear';
     procedure mpq_set              (var Dest : mpq_t; protected var
       Src : mpq_t); asmname '__gmpq_set';
     procedure mpq_set_z            (var Dest : mpq_t; protected var
       Src : mpz_t); asmname '__gmpq_set_z';
     procedure mpq_set_ui           (var Dest : mpq_t; Nom, Den :
       MedCard); asmname '__gmpq_set_ui';
     procedure mpq_set_si           (var Dest : mpq_t; Nom : MedInt;
       Den : MedCard); asmname '__gmpq_set_si';
     
     procedure mpq_add              (var Dest : mpq_t; protected var
       Src1, Src2 : mpq_t); asmname '__gmpq_add';
     procedure mpq_sub              (var Dest : mpq_t; protected var
       Src1, Src2 : mpq_t); asmname '__gmpq_sub';
     procedure mpq_mul              (var Dest : mpq_t; protected var
       Src1, Src2 : mpq_t); asmname '__gmpq_mul';
     procedure mpq_div              (var Dest : mpq_t; protected var
       Src1, Src2 : mpq_t); asmname '__gmpq_div';
     procedure mpq_neg              (var Dest : mpq_t; protected var
       Src : mpq_t); asmname '__gmpq_neg';
     procedure mpq_inv              (var Dest : mpq_t; protected var
       Src : mpq_t); asmname '__gmpq_inv';
     
     function  mpq_cmp              (protected var Src1, Src2 : mpq_t) :
       Integer; asmname '__gmpq_cmp';
     function  mpq_cmp_ui           (protected var Src1 : mpq_t; Nom2,
       Den2 : MedCard) : Integer; asmname '__gmpq_cmp_ui';
     function  mpq_sgn              (protected var Src : mpq_t) :
       Integer;
     function  mpq_equal            (protected var Src1, Src2 : mpq_t) :
       Integer; asmname '__gmpq_equal';
     
     function  mpq_get_d            (protected var Src : mpq_t) : Double;
       asmname '__gmpq_get_d';
     procedure mpq_set_num          (var Dest : mpq_t; protected var
       Src : mpz_t); asmname '__gmpq_set_num';
     procedure mpq_set_den          (var Dest : mpq_t; protected var
       Src : mpz_t); asmname '__gmpq_set_den';
     procedure mpq_get_num          (var Dest : mpz_t; protected var
       Src : mpq_t); asmname '__gmpq_get_num';
     procedure mpq_get_den          (var Dest : mpz_t; protected var
       Src : mpq_t); asmname '__gmpq_get_den';
     
     {**************** Float (i.e. R) routines.  ****************}
     
     procedure mpf_set_default_prec (Precision : MedCard);
       asmname '__gmpf_set_default_prec';
     procedure mpf_init             (var Dest : mpf_t);
       asmname '__gmpf_init';
     procedure mpf_init2            (var Dest : mpf_t; Precision :
       MedCard); asmname '__gmpf_init2';
     procedure mpf_clear            (var Dest : mpf_t);
       asmname '__gmpf_clear';
     procedure mpf_set_prec         (var Dest : mpf_t; Precision :
       MedCard); asmname '__gmpf_set_prec';
     function  mpf_get_prec         (protected var Src : mpf_t) :
       MedCard; asmname '__gmpf_get_prec';
     procedure mpf_set_prec_raw     (var Dest : mpf_t; Precision :
       MedCard); asmname '__gmpf_set_prec_raw';
     
     procedure mpf_set              (var Dest : mpf_t; protected var
       Src : mpf_t); asmname '__gmpf_set';
     procedure mpf_set_ui           (var Dest : mpf_t; Src : MedCard);
       asmname '__gmpf_set_ui';
     procedure mpf_set_si           (var Dest : mpf_t; Src : MedInt);
       asmname '__gmpf_set_si';
     procedure mpf_set_d            (var Dest : mpf_t; Src : Double);
       asmname '__gmpf_set_d';
     procedure mpf_set_z            (var Dest : mpf_t; protected var
       Src : mpz_t); asmname '__gmpf_set_z';
     procedure mpf_set_q            (var Dest : mpf_t; protected var
       Src : mpq_t); asmname '__gmpf_set_q';
     function  mpf_set_str          (var Dest : mpf_t; Src : CString;
       Base : Integer) : Integer; asmname '__gmpf_set_str';
     
     procedure mpf_init_set         (var Dest : mpf_t; protected var
       Src : mpf_t); asmname '__gmpf_init_set';
     procedure mpf_init_set_ui      (var Dest : mpf_t; Src : MedCard);
       asmname '__gmpf_init_set_ui';
     procedure mpf_init_set_si      (var Dest : mpf_t; Src : MedInt);
       asmname '__gmpf_init_set_si';
     procedure mpf_init_set_d       (var Dest : mpf_t; Src : Double);
       asmname '__gmpf_init_set_d';
     function  mpf_init_set_str     (var Dest : mpf_t; Src : CString;
       Base : Integer) : Integer; asmname '__gmpf_init_set_str';
     
     function  mpf_get_d            (protected var Src : mpf_t) : Double;
       asmname '__gmpf_get_d';
     { Pass nil for Dest to let the function allocate memory for it }
     function  mpf_get_str          (Dest : CString; var Exponent :
       mp_exp_t; Base : Integer;
                                     NumberOfDigits : SizeType; protected
       var Src : mpf_t) : CString; asmname '__gmpf_get_str';
     
     procedure mpf_add              (var Dest : mpf_t; protected var
       Src1, Src2 : mpf_t); asmname '__gmpf_add';
     procedure mpf_add_ui           (var Dest : mpf_t; protected var
       Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_add_ui';
     procedure mpf_sub              (var Dest : mpf_t; protected var
       Src1, Src2 : mpf_t); asmname '__gmpf_sub';
     procedure mpf_ui_sub           (var Dest : mpf_t; Src1 : MedCard;
       protected var Src2 : mpf_t); asmname '__gmpf_ui_sub';
     procedure mpf_sub_ui           (var Dest : mpf_t; protected var
       Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_sub_ui';
     procedure mpf_mul              (var Dest : mpf_t; protected var
       Src1, Src2 : mpf_t); asmname '__gmpf_mul';
     procedure mpf_mul_ui           (var Dest : mpf_t; protected var
       Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_mul_ui';
     procedure mpf_div              (var Dest : mpf_t; protected var
       Src1, Src2 : mpf_t); asmname '__gmpf_div';
     procedure mpf_ui_div           (var Dest : mpf_t; Src1 : MedCard;
       protected var Src2 : mpf_t); asmname '__gmpf_ui_div';
     procedure mpf_div_ui           (var Dest : mpf_t; protected var
       Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_div_ui';
     procedure mpf_sqrt             (var Dest : mpf_t; protected var
       Src : mpf_t); asmname '__gmpf_sqrt';
     procedure mpf_sqrt_ui          (var Dest : mpf_t; Src : MedCard);
       asmname '__gmpf_sqrt_ui';
     procedure mpf_neg              (var Dest : mpf_t; protected var
       Src : mpf_t); asmname '__gmpf_neg';
     procedure mpf_abs              (var Dest : mpf_t; protected var
       Src : mpf_t); asmname '__gmpf_abs';
     procedure mpf_mul_2exp         (var Dest : mpf_t; protected var
       Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_mul_2exp';
     procedure mpf_div_2exp         (var Dest : mpf_t; protected var
       Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_div_2exp';
     
     function  mpf_cmp              (protected var Src1, Src2 : mpf_t) :
       Integer; asmname '__gmpf_cmp';
     function  mpf_cmp_si           (protected var Src1 : mpf_t; Src2 :
       MedInt) : Integer;
     function  mpf_cmp_ui           (protected var Src1 : mpf_t; Src2 :
       MedCard) : Integer;
     function  mpf_eq               (protected var Src1, Src2 : mpf_t;
       NumberOfBits : MedCard) : Integer; asmname '__gmpf_eq';
     procedure mpf_reldiff          (var Dest : mpf_t; protected var
       Src1, Src2 : mpf_t); asmname '__gmpf_reldiff';
     function  mpf_sgn              (protected var Src : mpf_t)  :
       Integer;
     
     procedure mpf_random2          (var Dest : mpf_t; MaxSize :
       mp_size_t; MaxExp : mp_exp_t); asmname '__gmpf_random2';
     
     {$if 0} (*@@ commented out because they use C file pointers *)
     function  mpz_inp_str          (var Dest : mpz_t; Src : CFilePtr;
       Base : Integer) : SizeType; asmname '__gmpz_inp_str';
     function  mpz_inp_raw          (var Dest : mpz_t; Src : CFilePtr) :
       SizeType ; asmname '__gmpz_inp_raw';
     function  mpz_out_str          (Dest : CFilePtr; Base : Integer;
       protected var Src : mpz_t) : SizeType; asmname '__gmpz_out_str';
     function  mpz_out_raw          (Dest : CFilePtr; protected var Src :
       mpz_t) : SizeType ; asmname '__gmpz_out_raw';
     (*@@ mpf_out_str has a bug in GMP 2.0.2: it writes a spurious #0
       before the exponent for negative numbers*)
     function  mpf_out_str          (Dest : CFilePtr; Base : Integer;
       NumberOfDigits : SizeType; protected var Src : mpf_t) : SizeType;
       asmname '__gmpf_out_str';
     function  mpf_inp_str          (var Dest : mpf_t; Src : CFilePtr;
       Base : Integer) : SizeType; asmname '__gmpf_inp_str';
     {$endif}
     
     { New declarations in GMP 3.x. @@ Mostly untested! }
     {$ifdef HAVE_GMP3}
     
     { Available random number generation algorithms. }
     type
       gmp_randalg_t = (GMPRandAlgLC { Linear congruential. });
     
     const
       GMPRandAlgDefault = GMPRandAlgLC;
     
     { Linear congruential data struct. }
     type
       gmp_randata_lc = record
         a : mpz_t; { Multiplier. }
         c : MedCard; { Adder. }
         m : mpz_t; { Modulus (valid only if m2exp = 0). }
         m2exp : MedCard; { If <> 0, modulus is 2 ^ m2exp. }
       end;
     
     type
       gmp_randstate_t = record
         Seed : mpz_t; { Current seed. }
         Alg : gmp_randalg_t;  { Algorithm used. }
         AlgData : record { Algorithm specific data. }
         case gmp_randalg_t of
           GMPRandAlgLC : (lc : ^gmp_randata_lc); { Linear congruential.
       }
         end
       end;
     
     procedure gmp_randinit         (var State : gmp_randstate_t; Alg :
       gmp_randalg_t; ...); asmname '__gmp_randinit';
     procedure gmp_randinit_lc      (var State : gmp_randstate_t; A :
       mpz_t; C : MedCard; M : mpz_t); asmname '__gmp_randinit_lc';
     procedure gmp_randinit_lc_2exp (var State : gmp_randstate_t; A :
       mpz_t; C : MedCard; M2Exp : MedCard);
       asmname '__gmp_randinit_lc_2exp';
     procedure gmp_randseed         (var State : gmp_randstate_t; Seed :
       mpz_t); asmname '__gmp_randseed';
     procedure gmp_randseed_ui      (var State : gmp_randstate_t; Seed :
       MedCard); asmname '__gmp_randseed_ui';
     procedure gmp_randclear        (var State : gmp_randstate_t);
       asmname '__gmp_randclear';
     
     procedure mpz_addmul_ui        (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_addmul_ui';
     procedure mpz_bin_ui           (var Dest : mpz_t; protected var
       Src1 : mpz_t; Src2 : MedCard); asmname '__gmpz_bin_ui';
     procedure mpz_bin_uiui         (var Dest : mpz_t; Src1, Src2 :
       MedCard); asmname '__gmpz_bin_uiui';
     function  mpz_cmpabs           (protected var Src1, Src2 : mpz_t) :
       Integer; asmname '__gmpz_cmpabs';
     function  mpz_cmpabs_ui        (protected var Src1 : mpz_t; Src2 :
       MedCard) : Integer; asmname '__gmpz_cmpabs_ui';
     procedure mpz_dump             (protected var Src : mpz_t);
       asmname '__gmpz_dump';
     procedure mpz_fib_ui           (var Dest : mpz_t; Src : MedCard);
       asmname '__gmpz_fib_ui';
     function  mpz_fits_sint_p      (protected var Src : mpz_t) :
       Integer; asmname '__gmpz_fits_sint_p';
     function  mpz_fits_slong_p     (protected var Src : mpz_t) :
       Integer; asmname '__gmpz_fits_slong_p';
     function  mpz_fits_sshort_p    (protected var Src : mpz_t) :
       Integer; asmname '__gmpz_fits_sshort_p';
     function  mpz_fits_uint_p      (protected var Src : mpz_t) :
       Integer; asmname '__gmpz_fits_uint_p';
     function  mpz_fits_ulong_p     (protected var Src : mpz_t) :
       Integer; asmname '__gmpz_fits_ulong_p';
     function  mpz_fits_ushort_p    (protected var Src : mpz_t) :
       Integer; asmname '__gmpz_fits_ushort_p';
     procedure mpz_lcm              (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_lcm';
     procedure mpz_nextprime        (var Dest : mpz_t; protected var
       Src : mpz_t); asmname '__gmpz_nextprime';
     function  mpz_perfect_power_p  (protected var Src : mpz_t) :
       Integer; asmname '__gmpz_perfect_power_p';
     function  mpz_remove           (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t) : MedCard; asmname '__gmpz_remove';
     function  mpz_root             (var Dest : mpz_t; protected var
       Src : mpz_t; N : MedCard) : Integer; asmname '__gmpz_root';
     procedure mpz_rrandomb         (var ROP : mpz_t; var State :
       gmp_randstate_t; N : MedCard); asmname '__gmpz_rrandomb';
     procedure mpz_swap             (var v1, v2 : mpz_t);
       asmname '__gmpz_swap';
     function  mpz_tdiv_ui          (protected var Src1 : mpz_t; Src2 :
       MedCard) : MedCard; asmname '__gmpz_tdiv_ui';
     function  mpz_tstbit           (protected var Src1 : mpz_t; Src2 :
       MedCard) : Integer; asmname '__gmpz_tstbit';
     procedure mpz_urandomb         (ROP : mpz_t; var State :
       gmp_randstate_t; N : MedCard); asmname '__gmpz_urandomb';
     procedure mpz_urandomm         (ROP : mpz_t; var State :
       gmp_randstate_t; N : mpz_t); asmname '__gmpz_urandomm';
     procedure mpz_xor              (var Dest : mpz_t; protected var
       Src1, Src2 : mpz_t); asmname '__gmpz_xor';
     
     procedure mpq_set_d            (var Dest : mpq_t; Src : Double);
       asmname '__gmpq_set_d';
     
     procedure mpf_ceil             (var Dest : mpf_t; protected var
       Src : mpf_t); asmname '__gmpf_ceil';
     procedure mpf_floor            (var Dest : mpf_t; protected var
       Src : mpf_t); asmname '__gmpf_floor';
     procedure mpf_pow_ui           (var Dest : mpf_t; protected var
       Src1 : mpf_t; Src2 : MedCard); asmname '__gmpf_pow_ui';
     procedure mpf_trunc            (var Dest : mpf_t; protected var
       Src : mpf_t); asmname '__gmpf_trunc';
     procedure mpf_urandomb         (ROP : mpf_t; var State :
       gmp_randstate_t; N : MedCard); asmname '__gmpf_urandomb';
     
     const
       GMPErrorNone = 0;
       GMPErrorUnsupportedArgument = 1;
       GMPErrorDivisionByZero = 2;
       GMPErrorSqrtOfNegative = 4;
       GMPErrorInvalidArgument = 8;
       GMPErrorAllocate = 16;
     
     var
       gmp_errno : Integer; asmname '__gmp_errno'; external;
     
     {$endif}
     
     { Extensions to the GMP library, implemented in this unit }
     
     procedure mpf_exp    (var Dest : mpf_t; protected var Src : mpf_t);
     procedure mpf_ln     (var Dest : mpf_t; protected var Src : mpf_t);
     procedure mpf_pow    (var Dest : mpf_t; protected var Src1, Src2 :
       mpf_t);
     procedure mpf_arctan (var c : mpf_t; protected var x : mpf_t);
     procedure mpf_pi     (var c : mpf_t);


File: gpc,  Node: GPCUtil,  Next: HeapMon,  Prev: GMP,  Up: GPC Units

7.13.6 Turbo Power compatibility, etc.
--------------------------------------

   The following listing contains the interface of the GPCUtil unit.

   This unit provides some utility routines for compatibility to some
units available for BP, like some `Turbo Power' units.

     {
     Some utility routines for compatibility to some units available for
     BP, like some `Turbo Power' units.
     
     @@NOTE - SOME OF THE ROUTINES IN THIS UNIT MAY NOT WORK CORRECTLY.
     TEST CAREFULLY AND USE WITH CARE!
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Authors: Prof. Abimbola A. Olowofoyeku <African_Chief@bigfoot.com>
              Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit GPCUtil;
     
     interface
     
     uses GPC;
     
     { Replace all occurences of OldC with NewC in s and return the
       result }
     function  ReplaceChar (const s : String; OldC, NewC : Char) :
       TString;
     
     { Return the current working directory }
     function  ThisDirectory : TString;
       asmname '_p_get_current_directory';
     
     { Does a directory exist? }
     function  IsDirectory (const aFileName : String) : Boolean;
       asmname '_p_directory_exists';
     
     { Break a string into 2 parts, using Ch as a marker }
     function  BreakStr (const Src : String; var Dest1, Dest2 : String;
       Ch : Char) : Boolean;
     
     { Convert a CString to an Integer }
     function  PChar2Int (s : CString) : Integer;
     
     { Convert a CString to a LongInt }
     function  PChar2Long (s : CString) : LongInt;
     
     { Convert a CString to a Double }
     function  PChar2Double (s : CString) : Double;
     
     { Search for s as an executable in the path and return its location
       (full pathname) }
     function  PathLocate (const s : String) : TString;
     
     { Copy file Src to Dest and return the number of bytes written }
     function  CopyFile (const Src, Dest : String; BufSize : Integer) :
       LongInt;
     
     { Copy file Src to Dest and return the number of bytes written;
       report the number of bytes written versus total size of the source
       file }
     function  CopyFileEx (const Src, Dest : String; BufSize : Integer;
       function Report (Reached, Total : LongInt) : LongInt) : LongInt;
     
     { Turbo Power compatibility }
     
     { Execute the program prog. Dummy1 and Dummy2 are for compatibility
       only; they are ignored. }
     function  ExecDos (const Prog : String; Dummy1 : Boolean; Dummy2 :
       Pointer) : Integer;
     
     { Return whether Src exists in the path as an executable -- if so
       return its full location in Dest }
     function  ExistOnPath (const Src : String; var Dest : String) :
       Boolean;
     
     { Does file name s exist? }
     function  ExistFile (const aFileName : String) : Boolean;
       asmname '_p_file_exists';
     
     { Return just the directory path of Path. Returns DirSelf +
       DirSeparator if Path contains no directory. }
     function  JustPathName (const Path : String) : TString;
       asmname '_p_dir_from_path';
     
     { Return just the file name part without extension of Path. Empty if
       Path contains no file name. }
     function  JustFileName (const Path : String) : TString;
       asmname '_p_name_from_path';
     
     { Return just the extension of Path. Empty if Path contains no
       extension. }
     function  JustExtension (const Path : String) : TString;
       asmname '_p_ext_from_path';
     
     { Change the extension of s to Ext (do not include the dot!) }
     function  ForceExtension (const s, Ext : String) : TString;
     
     { Return the full pathname of Path }
     function  FullPathName (const Path : String) : TString;
       asmname '_p_fexpand';
     
     { Add a DirSeparator to the end of s if there is not already one }
     function  AddBackSlash (const s : String) : TString;
       asmname '_p_forceadddirseparator';
     
     { Convert Integer to PChar; uses CStringNew to allocate memory for
       the result, so you must call StrDispose to free the memory later }
     function  Int2PChar (i : Integer) : PChar;
     
     { Convert Integer to string }
     function  Int2Str (i : Integer) : TString;
     
     { Convert string to Integer }
     function  Str2Int (const s : String; var i : Integer) : Boolean;
     
     { Convert string to LongInt }
     function  Str2Long (const s : String; var i : LongInt) : Boolean;
     
     { Convert string to Double }
     function  Str2Real (const s : String; var i : Double) : Boolean;
     
     { Return a string stripped of leading spaces }
     function  TrimLead (const s : String) : TString;
       asmname '_p_trimleft_str';
     
     { Return a string stripped of trailing spaces }
     function  TrimTrail (const s : String) : TString;
       asmname '_p_trimright_str';
     
     { Return a string stripped of leading and trailing spaces }
     function  Trim (const s : String) : TString;
       asmname '_p_trimboth_str';
     
     { Return a string right-padded to length Len with ch }
     function  PadCh (const s : String; ch : Char; Len : Integer) :
       TString;
     
     { Return a string right-padded to length Len with spaces }
     function  Pad (const s : String; Len : Integer) : TString;
     
     { Return a string left-padded to length Len with ch }
     function  LeftPadCh (const s : String; ch : Char; Len : Byte) :
       TString;
     
     { Return a string left-padded to length Len with blanks }
     function  LeftPad (const s : String; Len : Integer) : TString;
     
     { Convert a string to lowercase }
     function  StLoCase (const s : String) : TString;
       asmname '_p_locase_str';
     
     { Convert a string to uppercase }
     function  StUpCase (const s : String) : TString;
       asmname '_p_upcase_str';
     
     { Uniform access to big memory blocks for GPC and BP. Of course, for
       programs that are meant only for GPC, you can use the usual
       New/Dispose
       routines. But for programs that should compile with GPC and BP,
       you can
       use the following routines for GPC. In the GPC unit for BP
       (gpc-bp.pas),
       you can find emulations for BP that try to provide access to as
       much
       memory as possible, despite the limitations of BP. The backdraw is
       that
       this memory cannot be used freely, but only with the following
       moving
       routines. }
     
     type
       PBigMem = ^TBigMem;
       TBigMem (MaxNumber : Integer) = record
         { Public fields }
         Number, BlockSize : SizeType;
         Mappable : Boolean;
         { Private fields }
         Pointers : array [1 .. MaxNumber] of ^Byte
       end;
     
     { Note: the number of blocks actually allocated may be smaller than
       WantedNumber. Check the Number field of the result. }
     function  AllocateBigMem (WantedNumber, aBlockSize : SizeType;
       WantMappable : Boolean) : PBigMem;
     procedure DisposeBigMem (p : PBigMem);
     procedure MoveToBigMem (var Source; p : PBigMem; BlockNumber :
       SizeType);
     procedure MoveFromBigMem (p : PBigMem; BlockNumber : SizeType; var
       Dest);
     { Maps a big memory block into normal addressable memory and returns
       its address. The memory must have been allocated with
       WantMappable = True. The mapping is only valid until the next
       MapBigMem call. }
     function  MapBigMem (p : PBigMem; BlockNumber : SizeType) : Pointer;


File: gpc,  Node: HeapMon,  Next: MD5,  Prev: GPCUtil,  Up: GPC Units

7.13.7 Primitive heap checking
------------------------------

   The following listing contains the interface of the HeapMon unit.

   This unit provide a rather primitive means to watch the heap, i.e.
check if all pointers that were allocated are released again. This is
meant as a debugging help for avoiding memory leaks.

   More extensive heap checking is provided by libraries like `efence'
which can be used in GPC programs without special provisions.

     {
     A unit to watch the heap, i.e. check if all pointers that were
     allocated are released again. This is meant as a debugging help
     for avoiding memory leaks.
     
     Use it in the main program before all other units. When, at the
     end of the program, some pointers that were allocated, have not
     been released, the unit prints a message to StdErr. Only pointers
     allocated via the Pascal mechanisms (New, GetMem) are tracked, not
     pointers allocated with direct libc calls or from C code. After a
     runtime error, pointers are not checked.
     
     Note that many units and libraries allocate memory for their own
     purposes and don't always release it at the end. Therefore, the
     usefulness of this unit is rather limited.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     
     unit HeapMon;
     
     interface
     
     uses GPC;
     
     { This unit has an empty interface. It is automatically activated
       when used. }


File: gpc,  Node: MD5,  Next: Overlay,  Prev: HeapMon,  Up: GPC Units

7.13.8 `MD5' Message Digests
----------------------------

   The following listing contains the interface of the MD5 unit.

   This unit provides functions to compute `MD5' message digest of
files or memory blocks, according to the definition of `MD5' in `RFC
1321' from April 1992.

     {
     Functions to compute MD5 message digest of files or memory blocks,
     according to the definition of MD5 in RFC 1321 from April 1992.
     
     IMPORTANT NOTE: This unit is distributed under the GNU GPL, NOT
     under the GNU LGPL under which most of the other GPC units are
     distributed. This means that you must distribute any code that
     uses this unit under the GPL as well, which means that you have to
     make the source code available whenever you distribute a binary of
     the code, and that you must allow recipients to modify the code
     and redistribute it under the GPL.
     
     Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
     
     Based on the C code written by Ulrich Drepper
     <drepper@gnu.ai.mit.edu>, 1995 as part of the GNU C Library.
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit MD5;
     
     interface
     
     uses GPC;
     
     { Representation of a MD5 value. It is always in little endian byte
       order and therefore portable. }
     type
       Card8 = Cardinal (8);
       TMD5 = array [1 .. 16] of Card8;
     
     { Computes MD5 message digest for Length bytes in Buffer. }
     procedure MD5Buffer (const Buffer; Length : SizeType; var MD5 :
       TMD5); asmname '_p_md5_buffer';
     
     { Computes MD5 message digest for the contents of the file f. }
     (*@@iocritical*)procedure MD5File (var f : File; var MD5 : TMD5);
       asmname '_p_md5_file';
     
     { Initializes a MD5 value with zeros. }
     procedure MD5Clear (var MD5 : TMD5); asmname '_p_md5_clear';
     
     { Compares two MD5 values for equality. }
     function MD5Compare (const Value1, Value2 : TMD5) : Boolean;
       asmname '_p_md5_compare';
     
     { Converts an MD5 value to a string. }
     function MD5Str ((*@@fjf382 const*) MD5 : TMD5) = s : TString;
       asmname '_p_md5_str';
     
     { Converts a string to an MD5 value. Returns True if successful. }
     function MD5Val (const s : String; var MD5 : TMD5) : Boolean;
       asmname '_p_md5_val';
     
     { Composes two MD5 values to a single one. }
     function MD5Compose (const Value1, Value2 : TMD5) = Dest : TMD5;
       asmname '_p_md5_compose';


File: gpc,  Node: Overlay,  Next: Pipe,  Prev: MD5,  Up: GPC Units

7.13.9 BP compatibility: Overlay
--------------------------------

   The following listing contains the interface of the Overlay unit.

   This is just a dummy replacement for BP's `Overlay' unit, since GPC
doesn't need overlays.

     {
     Dummy BP compatible overlay unit for GPC
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     
     unit Overlay;
     
     interface
     
     const
       ovrOk = 0;
       ovrError = - 1;
       ovrNotFound = - 2;
       ovrNoMemory = - 3;
       ovrIOError = - 4;
       ovrNoEMSDriver = - 5;
       ovrNoEMSMemory = - 6;
     
     const
       OvrEmsPages  : Word = 0;
       OvrTrapCount : Word = 0;
       OvrLoadCount : Word = 0;
       OvrFileMode  : Byte = 0;
     
     type
       OvrReadFunc = function (OvrSeg : Word) : Integer;
     
     var
       OvrReadBuf : OvrReadFunc;
       OvrResult  : Integer = 0;
     
     procedure OvrInit (aFileName : String);
     procedure OvrInitEMS;
     procedure OvrSetBuf (Size : LongInt);
     function  OvrGetBuf : LongInt;
     procedure OvrSetRetry (Size : LongInt);
     function  OvrGetRetry : LongInt;
     procedure OvrClearBuf;


File: gpc,  Node: Pipe,  Next: Ports,  Prev: Overlay,  Up: GPC Units

7.13.10 Start a child process, connected with pipes, also on Dos
----------------------------------------------------------------

   The following listing contains the interface of the Pipe unit.

   This unit provides routines to start a child process and write
to/read from its Input/Output/StdErr via pipes. All of this is emulated
transparently under Dos as far as possible.

     {
     Piping data from and to processes and process signaling
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     { Keep this consistent with the one in pipec.c }
     {$if defined(MSDOS) or defined(__MINGW32__)}
     {$define NOFORK}
     {$endif}
     
     unit Pipe;
     
     interface
     
     uses GPC;
     
     (*$local W-*)type PPStrings = ^TPStrings;TPStrings (Count: Cardinal)
       = array [1 .. Count] of ^String; (*@@two unit bug with definition
       in gpc.pas in programs using these two units*) (*$endlocal*)
     
     const
       PipeForking = {$ifdef NOFORK} False {$else} True {$endif};
     
     type
       TProcedure = procedure;
     
       PWaitPIDResult = ^TWaitPIDResult;
       TWaitPIDResult = (PIDNothing, PIDExited, PIDSignaled, PIDStopped,
       PIDUnknown);
     
       PPipeProcess = ^TPipeProcess;
       TPipeProcess = record
         PID       : Integer;        { Process ID of process forked }
         SignalPID : Integer;        { Process ID to send the signal to.
                                       Equals PID by default }
         OpenPipes : Integer;        { Number of pipes to/from the
                                       process, for internal use }
         Signal    : Integer;        { Send this signal (if not 0) to the
                                       process after all pipes have been
                                       closed after some time }
         Seconds   : Integer;        { Wait so many seconds before
                                       sending the signal if the process
                                       has not terminated by itself }
         Wait      : Boolean;        { Wait for the process, even longer
                                       than Seconds seconds, after
                                       sending the signal (if any) }
         Result    : PWaitPIDResult; { Default nil. If a pointer to a
                                       variable is stored here, its
                                       destination will contain the
                                       information whether the process
                                       terminated by itself, or was
                                       terminated or stopped by a signal,
                                       when waiting after closing the
                                       pipes }
         Status    : ^Integer;       { Default nil. If a pointer to a
                                       variable is stored here, its
                                       destination will contain the exit
                                       status if the process terminated
                                       by itself, or the number of the
                                       signal otherwise, when waiting
                                       after closing the pipes }
       end;
     
     const
       EFork  = 600; { cannot fork `%s'' }
       ESpawn = 601; { cannot spawn `%s'' }
     
     var
       { Default values for TPipeProcess records created by Pipe }
       DefaultPipeSignal  : Integer = 0;
       DefaultPipeSeconds : Integer = 0;
       DefaultPipeWait    : Boolean = True;
     
     {
       The procedure Pipe starts a process whose name is given by
       ProcessName, with the given parameters (can be null if no
       parameters) and environment, and create pipes from and/or to the
       process' standard input/output/error. ProcessName is searched for
       in the PATH with FSearchExecutable. Any of ToInputFile,
       FromOutputFile and FromStdErrFile can be null if the corresponding
       pipe is not wanted. FromOutputFile and FromStdErrFile may be
       identical, in which case standard output and standard error are
       redirected to the same pipe. The behaviour of other pairs of files
       being identical is undefined, and useless, anyway. The files are
       Assigned and Reset or Rewritten as appropriate. Errors are
       returned in IOResult. If Process is not null, a pointer to a
       record is stored there, from which the PID of the process created
       can be read, and by writing to which the action after all pipes
       have been closed can be changed. (The record is automatically
       Dispose'd of after all pipes have been closed.) If automatic
       waiting is turned off, the caller should get the PID from the
       record before it's Dispose'd of, and wait for the process sometime
       in order to avoid zombies. If no redirections are performed (i.e.,
       all 3 files are null), the caller should wait for the process with
       WaitPipeProcess. When an error occurs, Process is not assigned to,
       and the state of the files is undefined, so be sure to check
       IOResult before going on.
     
       ChildProc, if not nil, is called in the child process after
       forking and redirecting I/O, but before executing the new process.
       It can even be called instead of executing a new process
       (ProcessName can be empty then).
     
       The procedure even works under Dos, but, of course, in a limited
       sense: if ToInputFile is used, the process will not actually be
       started until ToInputFile is closed. Signal, Seconds and Wait of
       TPipeProcess are ignored, and PID and SignalPID do not contain a
       Process ID, but an internal value without any meaning to the
       caller. Result will always be PIDExited. So, Status is the only
       interesting field (but Result should also be checked). Since there
       is no forking under Dos, ChildProc, if not nil, is called in the
       main process before spawning the program. So, to be portable, it
       should not do any things that would influence the process after
       the return of the Pipe function.
     
       The only portable way to use "pipes" in both directions is to call
       `Pipe', write all the Input data to ToInputFile, close
       ToInputFile, and then read the Output and StdErr data from
       FromOutputFile and FromStdErrFile. However, since the capacity of
       pipes is limited, one should also check for Data from
       FromOutputFile and FromStdErrFile (using CanRead, IOSelect or
       IOSelectRead) while writing the Input data (under Dos, there
       simply won't be any data then, but checking for data doesn't do
       any harm). Please see pipedemo.pas for an example.
     }
     (*@@IO critical*) procedure Pipe (var ToInputFile, FromOutputFile,
       FromStdErrFile : AnyFile; (*@@fjf265 const*) ProcessName : String;
       protected var Parameters : TPStrings; ProcessEnvironment :
       PCStrings; var Process : PPipeProcess; ChildProc : TProcedure);
     
     {
       Waits for a process created by Pipe as determined in the Process
       record. (Process is Dispose'd of afterwards.) Returns True if
       successful.
     }
     function WaitPipeProcess (Process : PPipeProcess) : Boolean;


File: gpc,  Node: Ports,  Next: Printer,  Prev: Pipe,  Up: GPC Units

7.13.11 BP compatibility (partly): `Port', `PortW' arrays
---------------------------------------------------------

   The following listing contains the interface of the Ports unit.

   This unit provides access routines for the hardware ports on the
x86, as a partial replacement for BP's `Port' and `PortW' pseudo arrays.

   Since port access is platform-specific, this unit cannot be used in
code intended to be portable. Even on the x86, its use can often be
avoided - e.g. Linux provides a number of `ioctl' functions, and DJGPP
provides some routines to achieve things that would require port access
under BP. Therefore, it is recommended to avoid using this unit
whenever possible.

     {
     Access functions for I/O ports for GPC on an x86 platform. This unit
     is *not* portable. It works only on x86 platforms (tested under
     Linux and DJGPP). It is provided here only to serve as a replacement
     for BP's Port and PortW pseudo arrays.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$ifndef __i386__}
     {$error The Ports unit is only for the x86 platform}
     {$endif}
     
     unit Ports;
     
     interface
     
     { Port access functions }
     function  InPortB  (PortNumber : ShortWord) : Byte;
     function  InPortW  (PortNumber : ShortWord) : ShortWord;
     procedure OutPortB (PortNumber : ShortWord; aValue : Byte);
     procedure OutPortW (PortNumber, aValue : ShortWord);
     
     { libc functions for getting access to the ports -- only for root
       processes, of course -- and to give up root privileges after
       getting access to the ports for setuid root programs. Dummies
       under DJGPP. }
     function  IOPerm (From, Num : MedCard; On : Integer) : Integer;
       asmname 'ioperm';
     function  IOPL (Level : Integer) : Integer; asmname 'iopl';
     function  SetEUID (EUID : Integer) : Integer; asmname 'seteuid';


File: gpc,  Node: Printer,  Next: RegEx,  Prev: Ports,  Up: GPC Units

7.13.12 BP compatibility: Printer, portable
-------------------------------------------

   The following listing contains the interface of the Printer unit.

   This unit provides printer access, compatible to BP's `Printer'
unit, for Dos (using printer devices) and Unix systems (using printer
utilities).

   For BP compatibility, the variable `Lst' is provided, but for newly
written programs, it is recommended to use the `AssignPrinter'
procedure on a text file, and close the file when done (thereby
committing the printer job). This method allows for sending multiple
printer jobs in the same program.

     {
     BP compatible printer unit with extensions
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit Printer;
     
     interface
     
     {$ifdef __OS_DOS__}
     
     { Dos-like systems: writing to a printer device }
     
     uses GPC;
     
     var
       { The file name to write printer output into }
       PrinterDeviceName : ^String = @'prn';
     
     {$else}
     
     { Unix-like systems: printing via a printer program }
     
     uses GPC, Pipe;
     
     const
       EPrinterRead = 610; { printer can only be opened for writing }
     
     var
       { The file name of the printer program. If it contains a '/', it
         will be taken as a complete path, otherwise the file name will
         be searched for in the PATH with FSearchExecutable. }
       PrinterCommand : ^String = @'lpr';
     
       { Optional command line parameters for the printer program.
         Ignored when nil. }
       PrinterArguments : ^TPStrings = nil;
     
       { How to deal with the printer spooler after the printer pipe is
         closed, cf. the Pipe unit. }
       PrinterPipeSignal  : Integer = 0;
       PrinterPipeSeconds : Integer = 0;
       PrinterPipeWait    : Boolean = True;
     
     {$endif}
     
     { Text file opened to default printer }
     var
       Lst : Text;
     
     { Assign a file to the printer. Lst will be assigned to the default
       printer at program start, but other files can be assigned to the
       same or other printers (possibly after changing the variables
       above). SpoolerOutput, if not null, will be redirected from the
       printer spooler's standard output and error. If you use this, note
       that a deadlock might arise when trying to write data to the
       spooler while its output is not being read, though this seems
       quite unlikely, since most printer spoolers don't write so much
       output that could fill a pipe. Under Dos, where no spooler is
       involved, SpoolerOutput, if not null, will be reset to an empty
       file for compatibility. }
     procedure AssignPrinter (var f : AnyFile; var SpoolerOutput :
       AnyFile);


File: gpc,  Node: RegEx,  Next: Strings,  Prev: Printer,  Up: GPC Units

7.13.13 Regular Expression matching and substituting
----------------------------------------------------

   The following listing contains the interface of the RegEx unit.

   This unit provides routines to match strings against regular
expressions and perform substitutions using matched subexpressions.
Regular expressions are strings with some characters having special
meanings. They describe (match) a class of strings. They are similar to
wild cards used in file name matching, but much more powerful.

   To use this unit, you will need the `rx' library which can be found
in `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/'.

     {$nested-comments}
     {
     Regular expression matching and replacement
     
     The RegEx unit provides routines to match strings against regular
     expressions and perform substitutions using matched subexpressions.
     
     To use the RegEx unit, you will need the rx library which can be
     found in ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/libs/ .
     
     Regular expressions are strings with some characters having special
     meanings. They describe (match) a class of strings. They are similar
     to wild cards used in file name matching, but much more powerful.
     
     There are two kinds of regular expressions supported by this unit,
     basic and extended regular expressions. The difference between them
     is not functionality, but only syntax. The following is a short
     overview of regular expressions. For a more thorough explanation see
     the literature, or the documentation of the rx library, or man pages
     of programs like grep(1) and sed(1).
     
     Basic           Extended        Meaning
     `.'             `.'             matches any single character
     `[aei-z]'       `[aei-z]'       matches either `a', `e', or any
                                     character from `i' to `z'
     `[^aei-z]'      `[^aei-z]'      matches any character but `a', `e',
                                     or `i' .. `z'
                                     To include in such a list the the
                                     characters `]', `^', or `-', put
                                     them first, anywhere but first, or
                                     first or last, resp.
     `[[:alnum:]]'   `[[:alnum:]]'   matches any alphanumeric character
     `[^[:digit:]]'  `[^[:digit:]]'  matches anything but a digit
     `[a[:space:]]'  `[a[:space:]]'  matches the letter `a' or a space
                                     character (space, tab)
     ...                             (there are more classes available)
     `\w'            `\w'            = [[:alnum:]]
     `\W'            `\W'            = [^[:alnum:]]
     `^'             `^'             matches the empty string at the
                                     beginning of a line
     `$'             `$'             matches the empty string at the end
                                     of a line
     `*'             `*'             matches zero or more occurences of
                                     the preceding expression
     `\+'            `+'             matches one or more occurences of
                                     the preceding expression
     `\?'            `?'             matches zero or one occurence of the
                                     preceding expression
     `\{N\}'         `{N}'           matches exactly N occurences of the
                                     preceding expression (N is an
                                     integer number)
     `\{M,N\}'       `{M,N}'         matches M to N occurences of the
                                     preceding expression (M and N are
                                     integer numbers, M <= N)
     `A B'           `A B'           matches A followed by B (A and B are
                                     regular expressions)
     `A\|B'          `A|B'           matches A or B (A and B are regular
                                     expressions)
     `\( \)'         `( )'           forms a subexpression, to override
                                     precedence, and for subexpression
                                     references
     `\7'            `\7'            matches the 7'th parenthesized
                                     subexpression (counted by their
                                     start in the regex), where 7 is a
                                     number from 1 to 9 ;-).
                                     *Please note:* using this feature
                                     can be *very* slow or take very much
                                     memory (exponential time and space
                                     in the worst case, if you know what
                                     that means...).
     `\'             `\'             quotes the following character if
                                     it's special (i.e. listed above)
     rest            rest            any other character matches itself
     
     Precedence, from highest to lowest:
     * parentheses (`()')
     * repetition (`*', `+', `?', `{}')
     * concatenation
     * alternation (`|')
     
     When performing substitutions using matched subexpressions of a
     regular expression (see `ReplaceSubExpressionReferences'), the
     replacement string can reference the whole matched expression with
     `&' or `\0', the 7th subexpression with `\7' (just like in the regex
     itself, but using it in replacements is not slow), and the 7th
     subexpression converted to upper/lower case with `\u7' or `\l7',
     resp. (which also works for the whole matched expression with `\u0'
     or `\l0'). A verbatim `&' or `\' can be specified with `\&' or `\\',
     resp.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     
     Please also note the license of the rx library.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit RegEx;
     
     interface
     
     uses GPC;
     
     const
       { `BasicRegExSpecialChars' contains all characters that have
         special meanings in basic regular expressions.
         `ExtRegExSpecialChars' contains those that have special meanings
         in extended regular expressions. }
       BasicRegExSpecialChars = ['.', '[', ']', '^', '$', '*', '\'];
       ExtRegExSpecialChars   =
       ['.', '[', ']', '^', '$', '*', '+', '?', '{', '}', '|', '(', ')', '\'];
     
     type
       { The type used by the routines of the `RegEx' unit to store
         regular expressions in an internal format. The fields RegEx,
         RegMatch, ErrorInternal, From and Length are only used
         internally. SubExpressions can be read after `NewRegEx' and will
         contain the number of parenthesized subexpressions. Error should
         be checked after `NewRegEx'. It will be `nil' when it succeeded,
         and contain an error message otherwise. }
       RegExType = record
         RegEx, RegMatch : Pointer;  { Internal }
         ErrorInternal : CString;    { Internal }
         From, Length : Integer;     { Internal }
         SubExpressions : Integer;
         Error : PString
       end;
     
     { Simple interface to regular expression mathing. Matches a regular
       expression against a string starting from a specified position.
       Returns the position of the first match, or 0 if it does not
       match, or the regular expression is invalid. }
     function  RegExPosFrom (const Expression : String; ExtendedRegEx,
       CaseInsensitive : Boolean; const s : String; From : Integer) :
       Integer; asmname '_p_regexposfrom';
     
     { Creates the internal format of a regular expression. If
       ExtendedRegEx is True, Expression is assumed to denote an extended
       regular expression, otherwise a basic regular expression.
       CaseInsensitive determines if the case of letters will be ignored
       when mathing the expression. If NewLines is True, `NewLine'
       characters in a string matched against the expression will be
       treated as dividing the string in multiple lines, so that `$' can
       match before the NewLine and `^' can match after. Also, `.' and
       `[^...]' will not match a NewLine then.}
     procedure NewRegEx (var RegEx : RegExType; const Expression :
       String; ExtendedRegEx, CaseInsensitive, NewLines : Boolean);
       asmname '_p_newregex';
     
     { Disposes of a regular expression created with `NewRegEx'. *Must*
       be used after `NewRegEx' before the RegEx variable becomes invalid
       (i.e., goes out of scope or a pointer pointing to it is Dispose'd
       of). }
     procedure DisposeRegEx (var RegEx : RegExType);
       asmname '_p_dispose_regex';
     
     { Matches a regular expression created with `NewRegEx' against a
       string. }
     function  MatchRegEx (var RegEx : RegExType; const s : String;
       NotBeginningOfLine, NotEndOfLine : Boolean) : Boolean;
       asmname '_p_matchregex';
     
     { Matches a regular expression created with `NewRegEx' against a
       string, starting from a specified position. }
     function  MatchRegExFrom (var RegEx : RegExType; const s : String;
       NotBeginningOfLine, NotEndOfLine : Boolean; From : Integer) :
       Boolean; asmname '_p_matchregexfrom';
     
     { Finds out where the regular expression matched, if `MatchRegEx' or
       `MatchRegExFrom' were successful. If n = 0, it returns the
       position of the whole match, otherwise the position of the n'th
       parenthesized subexpression. MatchPosition and MatchLength will
       contain the position (counted from 1) and length of the match, or
       0 if it didn't match. (Note: MatchLength can also be 0 for a
       successful empty match, so check MatchPosition for 0 to find out
       if it matched at all.) MatchPosition or MatchLength may be null
       and is ignored then. }
     procedure GetMatchRegEx (var RegEx : RegExType; n : Integer; var
       MatchPosition, MatchLength : Integer);
       asmname '_p_getmatch_regex';
     
     { Checks if the string s contains any quoted characters or
       (sub)expression references to the regular expression RegEx created
       with `NewRegEx'. These are `&' or `\0' for the whole matched
       expression (if OnlySub is not set) and `\1' .. `\9' for the n'th
       parenthesized subexpression. Returns 0 if it does not contain any,
       and the number of references and quoted characters if it does. If
       an invalid reference (i.e. a number bigger than the number of
       subexpressions in RegEx) is found, it returns the negative value
       of the (first) invalid reference. }
     function  FindSubExpressionReferences (var RegEx : RegExType; const
       s : String; OnlySub : Boolean) : Integer;
       asmname '_p_find_subexpressionreferences_regex';
     
     { Replaces (sub)expression references in ReplaceStr by the actual
       (sub)expressions and unquotes quoted characters. To be used after
       the regular expression RegEx created with `NewRegEx' was matched
       against s successfully with `MatchRegEx' or `MatchRegExFrom'. }
     function  ReplaceSubExpressionReferences (var RegEx : RegExType;
       const s, ReplaceStr : String) : TString;
       asmname '_p_replace_subexpressionreferences_regex';
     
     { Returns the string for a regular expression that matches exactly
       one character out of the given set. It can be combined with the
       usual operators to form more complex expressions. }
     function  CharSet2RegEx (const Characters : CharSet) : TString;
       asmname '_p_CharSet2RegEx';


File: gpc,  Node: Strings,  Next: StringUtils,  Prev: RegEx,  Up: GPC Units

7.13.14 BP compatibility: Strings
---------------------------------

   The following listing contains the interface of the Strings unit.

   This is a compatibility unit to BP's `Strings' unit to handle C
style `#0'-terminated strings.

   The same functionality and much more is available in the Run Time
System, *Note Run Time System::, under clearer names (starting with a
`CString' prefix),

   Moreover, the use of `#0'-terminated C-style strings (`PChar' or
`CString') is generally not recommended in GPC, since GPC provides ways
to deal with Pascal-style strings of arbitrary and dynamic size in a
comfortable way, as well as automatic conversion to C-style strings in
order to call external C functions.

   Therefore, using this unit is not recommended in newly written
programs.

     {
     BP compatible Strings unit
     
     Copyright (C) 1999-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     
     unit Strings;
     
     interface
     
     uses GPC;
     
     function  StrLen     (Src : CString) : SizeType;
       asmname '_p_strlen';
     function  StrEnd     (Src : CString) : CString; asmname '_p_strend';
     function  StrMove    (Dest, Source : CString; Count : SizeType) :
       CString; asmname '_p_strmove';
     function  StrCopy    (Dest, Source : CString) : CString;
       asmname '_p_strcpy';
     function  StrECopy   (Dest, Source : CString) : CString;
       asmname '_p_strecpy';
     function  StrLCopy   (Dest, Source : CString; MaxLen : SizeType) :
       CString; asmname '_p_strlcpy';
     function  StrPCopy   (Dest : CString; const Source : String) :
       CString; asmname '_p_cstringcopystring';
     function  StrCat     (Dest, Source : CString) : CString;
       asmname '_p_strcat';
     function  StrLCat    (Dest, Source : CString; MaxLen : SizeType) :
       CString; asmname '_p_strlcat';
     function  StrComp    (s1, s2 : CString) : Integer;
       asmname '_p_strcmp';
     function  StrIComp   (s1, s2 : CString) : Integer;
       asmname '_p_strcasecmp';
     function  StrLComp   (s1, s2 : CString; MaxLen : SizeType) :
       Integer; asmname '_p_strlcmp';
     function  StrLIComp  (s1, s2 : CString; MaxLen : SizeType) :
       Integer; asmname '_p_strlcasecmp';
     function  StrScan    (Src : CString; Ch : Char) : CString;
       asmname '_p_strscan';
     function  StrRScan   (Src : CString; Ch : Char) : CString;
       asmname '_p_strrscan';
     function  StrPos     (aString, SubString : CString) : CString;
       asmname '_p_strpos';
     function  StrRPos    (aString, SubString : CString) : CString;
       asmname '_p_strrpos';
     function  StrUpper   (s : CString) : CString; asmname '_p_strupper';
     function  StrLower   (s : CString) : CString; asmname '_p_strlower';
     function  StrPas     (aString : CString) : TString;
       asmname '_p_strpas';
     function  StrEmpty   (s : CString) : Boolean; asmname '_p_strempty';
     function  StrNew     (Src : CString) : CString; asmname '_p_strdup';
     procedure StrDispose (s : CString); asmname '_p_dispose';


File: gpc,  Node: StringUtils,  Next: System,  Prev: Strings,  Up: GPC Units

7.13.15 Higher level string handling
------------------------------------

   The following listing contains the interface of the StringUtils unit.

   This unit provides some routines for string handling on a higher
level than those provided by the RTS.

     {
     Some routines for string handling on a higher level than those
     provided by the RTS.
     
     Copyright (C) 1999-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000814}
     {$error This unit requires GPC release 20000814 or newer.}
     {$endif}
     
     unit StringUtils;
     
     interface
     
     uses GPC;
     
     { Appends Source to s, truncating the result if necessary. }
     procedure AppendStr (var s : String; const Source : String);
     
     { Cuts s to MaxLength characters. If s is already MaxLength
       characters or shorter, it doesn't change anything. }
     procedure StrCut (var s : String; MaxLength : Integer);
     
     { Returns the number of disjoint occurences of SubStr in s. Returns
       0 if SubStr is empty. }
     function  StrCount (const SubStr : String; s : String) : Integer;
     
     { Returns s, with all disjoint occurences of Source replaced by
       Dest. }
     function  StrReplace (const s, Source, Dest : String) : TString;
     
     { Sets of characters accepted for `True' and `False' by
       Char2Boolean and StrReadBoolean. }
     var
       CharactersTrue  : CharSet = ['Y', 'y'];
       CharactersFalse : CharSet = ['N', 'n'];
     
     { If ch is an element of CharactersTrue, Dest is set to True,
       otherwise if it is an element of CharactersFalse, Dest is set to
       False. In both cases True is returned. If ch is not an element of
       either set, Dest is set to False and False is returned. }
     function  Char2Boolean (ch : Char; var Dest : Boolean) : Boolean;
     
     { Converts a digit character to its numeric value. Handles every
       base up to 36 (0 .. 9, a .. z, upper and lower case recognized).
       Returns -1 if the character is not a digit at all. If you want to
       use it for a base < 36, you have to check if the result is smaller
       than the base and not equal to -1. }
     function  Char2Digit (ch : Char) : Integer;
     
     { Encode a string in a printable format (quoted printable and
       surrounded with `"'). All occurences of `"' within the string are
       encoded, so the result string contains exactly two `"' characters
       (at the beginning and ending). This is useful to store arbitrary
       strings in text files while keeping them as readable as possible
       (which is the goal of the quoted printable encoding in general,
       RFC 1521, section 5.1) and being able to read them back losslessly
       (with UnQuoteString). }
     function  QuoteString (const s : String) : TString;
     
     { Decode a string encoded by QuoteString (removing the `"' and
       expanding quoted printable encoded characters). Returns True if
       successful and False if the string has an invalid form. A string
       returned by QuoteString is always valid. }
     function  UnQuoteString (var s : String) : Boolean;
     
     { Decode a quoted-printable string (not enclosed in `"', unlike for
       UnQuoteString). Returns True if successful and False if the string
       has an invalid form. }
     function  UnQPString (var s : String) : Boolean;
     
     { Replaces all tab characters in s with the appropriate amount of
       spaces, assuming tab stops at every TabSize columns. Returns True
       if successful and False if the expanded string would exceed the
       capacity of s. In the latter case, some, but not all of the tabs
       in s may have been expanded. }
     function  ExpandTabs (var s : String; TabSize : Integer) : Boolean;
     
     { Returns s, with all occurences of C style escape sequences (e.g.
       `\n') replaced by the characters they mean. If AllowOctal is True,
       also octal character specifications (e.g. `\007') are replaced. If
       RemoveQuoteChars is True, any other backslashes are removed (e.g.
       `\*' -> `*' and `\\' -> `\'), otherwise they are kept, and also
       `\\' is left as two backslashes then. }
     function  ExpandCEscapeSequences (const s : String;
       RemoveQuoteChars, AllowOctal : Boolean) : TString;
     
     { String parsing routines }
     
     {
       All the following StrReadFoo functions behave similarly. They read
       items from a string s, starting at index i, to a variable Dest.
       They skip any space characters (spaces and tabs) by incrementing i
       first. They return True if successful, False otherwise. i is
       incremented accordingly if successful, otherwise i is left
       unchanged, apart from the skipping of space characters, and Dest
       is undefined. This behaviour makes it easy to use the functions in
       a row like this:
     
         i := 1;
         if StrReadInt    (s, i, Size)  and StrReadComma (s, i) and
            StrReadQuoted (s, i, Name)  and StrReadComma (s, i) and
            ...
            StrReadReal   (s, i, Angle) and (i > Length (s)) then ...
     
       (The check `i > Length (s)' is in case you don't want to accept
       trailing "garbage".)
     }
     
     { Just skip any space characters as described above. }
     procedure StrSkipSpaces (const s : String; var i : Integer);
     
     { Read a quoted string (as produced by QuoteString) from a string
       and unquote the result using UnQuoteString. It is considered
       failure if the result (unquoted) would be longer than the capacity
       of Dest.}
     function  StrReadQuoted (const s : String; var i : Integer; var
       Dest : String) : Boolean;
     
     { Read a string delimited with Delimiter from a string and return
       the result with the delimiters removed. It is considered failure
       if the result (without delimiters) would be longer than the
       capacity of Dest. }
     function  StrReadDelimited (const s : String; var i : Integer; var
       Dest : String; Delimiter : Char) : Boolean;
     
     { Read a word (consisting of anything but space characters and
       commas) from a string. It is considered failure if the result
       would be longer than the capacity of Dest. }
     function  StrReadWord (const s : String; var i : Integer; var Dest :
       String) : Boolean;
     
     { Check that a certain string is contained in s (after possible
       space characters). }
     function  StrReadConst (const s : String; var i : Integer; const
       Expected : String) : Boolean;
     
     { A simpler to use version of StrReadConst that expects a `,'. }
     function  StrReadComma (const s : String; var i : Integer) :
       Boolean;
     
     { Read an integer number from a string. }
     function  StrReadInt (const s : String; var i : Integer; var Dest :
       Integer) : Boolean;
     
     { Read a real number from a string. }
     function  StrReadReal (const s : String; var i : Integer; var Dest :
       Real) : Boolean;
     
     { Read a Boolean value, represented by a single character
       from CharactersTrue or CharactersFalse (cf. Char2Boolean), from a
       string. }
     function  StrReadBoolean (const s : String; var i : Integer; var
       Dest : Boolean) : Boolean;
     
     { Read an enumerated value, i.e., one of the entries of IDs, from a
       string, and stores the ordinal value, i.e., the index in IDs
       (always zero-based) in Dest. }
     function  StrReadEnum (const s : String; var i : Integer; var Dest :
       Integer; var IDs : array of PString) : Boolean;
     
     { String hash table }
     
     const
       DefaultHashSize = 1403;
     
     type
       THash = Cardinal;
     
       PStrHashList = ^TStrHashList;
       TStrHashList = record
         Next : PStrHashList;
         s : PString;
         i : Integer;
         p : Pointer
       end;
     
       PStrHashTable = ^TStrHashTable;
       TStrHashTable (Size : Cardinal) = record
         CaseSensitive : Boolean;
         Table : array [0 .. Size - 1] of PStrHashList
       end;
     
     function  HashString          (const s : String) : THash;
     function  NewStrHashTable     (Size : Cardinal; CaseSensitive :
       Boolean) : PStrHashTable;
     procedure AddStrHashTable     (HashTable : PStrHashTable; s :
       String; i : Integer; p : Pointer);
     procedure DeleteStrHashTable  (HashTable : PStrHashTable; s :
       String);
     function  SearchStrHashTable  (HashTable : PStrHashTable; const s :
       String; var p : Pointer) : Integer; { p may be null }
     procedure DisposeStrHashTable (HashTable : PStrHashTable);


File: gpc,  Node: System,  Next: Trap,  Prev: StringUtils,  Up: GPC Units

7.13.16 BP compatibility: System
--------------------------------

   The following listing contains the interface of the System unit.

   This unit contains only BP's more exotic routines which are not
recommended to be used in new programs. Most of their functionality can
be achieved by more standard means already.

   _Note:_ `MemAvail' and `MaxAvail', provided in this unit, cannot
easily be achieved by other means. However, it is not recommended to
use them on any multi-tasking system at all, where memory is a shared
resource. The notes in the unit give some hints about how to avoid
using them.

   On special request, i.e., by defining the conditionals
`__BP_TYPE_SIZES__' and/or `__BP_RANDOM__', the unit also provides BP
compatible integer type sizes and a 100% BP compatible pseudo random
number generator.

     {
     BP compatible System unit for GPC
     
     This unit is released as part of the GNU Pascal project. It
     implements some rather exotic BP compatibility features. Even many
     BP programs don't need them, but they're here for maximum
     compatibility. Most of BP's System unit's features are built into
     the compiler or the RTS.
     
     The unit depends on the conditional defines `__BP_TYPE_SIZES__' and
     `__BP_RANDOM__'. If `__BP_TYPE_SIZES__' is defined (with the
     `-D__BP_TYPE_SIZES__' option), the integer data types will be
     redefined to the sizes they have in BP or Delphi. Note that this
     might cause problems, e.g. when passing var parameters of integer
     types between units that do and don't use System. However, of the BP
     compatibility units, only Dos and WinDos use such parameters, and
     they have been taken care of so they work.
     
     If `__BP_RANDOM__' is defined (`-D__BP_RANDOM__'), this unit will
     provide an exactly BP compatible pseudo random number generator. In
     particular, the range for integer randoms will be truncated to 16
     bits like in BP. The RandSeed variable is provided, and if it's set
     to the same value as BP's RandSeed, it produces exactly the same
     sequence of pseudo random numbers that BP's pseudo random number
     generator does (whoever might need this... ;-). Even the Randomize
     function will behave exactly like in BP. However, this will not be
     noted unless one explicitly tests for it.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Authors: Peter Gerwinski <peter@gerwinski.de>
              Prof. Abimbola A. Olowofoyeku <African_Chief@bigfoot.com>
              Frank Heckenbach <frank@pascal.gnu.de>
              Dominik Freche <dominik.freche@gmx.net>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit System;
     
     interface
     
     uses GPC;
     
     var
       { Chain of procedures to be executed at the end of the program }
       ExitProc : ^procedure = nil;
     
       { Contains all the command line arguments passed to the program,
         concatenated, with spaces between them }
       CmdLine : CString;
     
       {$ifdef __BP_RANDOM__}
       { Random seed, initialized by Randomize, but can also be set
         explicitly }
       RandSeed : Integer (32) = 0;
       {$endif}
     
     type
       OrigInt = Integer;
       OrigWord = Word;
     
       { needed in the Dos unit }
       Int7 = Integer (7);
       Word16 = Word (16);
       Word32 = Word (32);
     
       { Delphi }
       SmallInt = Integer  (16);
       DWord    = Cardinal (32);
     
       { Short BP compatible type sizes if wanted }
       {$ifdef __BP_TYPE_SIZES__}
       ByteBool = Boolean  (8);
       WordBool = Boolean  (16);
       LongBool = Boolean  (32);
       Boolean  = ByteBool;      { important in packed records and arrays
       }
       ShortInt = Integer  (8);
       Byte     = Cardinal (8);
       Word     = Cardinal (16);
       LongInt  = Integer  (32);
       Comp     = Integer  (64);
       LongWord = Cardinal (32); { Delphi }
       Integer  = Integer  (16);
       {$endif}
     
       (*@@ doesn't work well (dialec3.pas) -- when GPC gets short
            strings, it will be unnecessary
       {$ifdef __BORLAND_PASCAL__}
       String = String [255];
       {$endif} *)
     
     const
       MaxInt     = High (Integer);
       MaxLongInt = High (LongInt);
     
     { Return the lowest-order byte of x }
     function  Lo (x : LongestInt) : Byte;
     
     { Return the lowest-but-one-order byte of x }
     function  Hi (x : LongestInt) : Byte;
     
     { Swap the lowest- and lowest-but-one-order bytes, mask out the
       higher ones }
     function  Swap (x : LongestInt) : Word;
     
     { Store the current directory name (on the given drive number if
       drive <> 0) in s }
     procedure GetDir (Drive : Byte; var s : String);
     
     { Dummy routine for compatibility. @@Use two overloaded versions
       rather than varargs when possible. }
     procedure SetTextBuf (var f : Text; var Buf; ...);
     
     { Mostly useless BP compatible variables }
     var
       SelectorInc : Word = $1000;
       Seg0040 : Word = $40;
       SegA000 : Word = $a000;
       SegB000 : Word = $b000;
       SegB800 : Word = $b800;
       Test8086 : Byte = 2;
       Test8087 : Byte = 3; { floating-point arithmetic is emulated
                              transparently by the OS if not present
                              in hardware }
       OvrCodeList : Word = 0;
       OvrHeapSize : Word = 0;
       OvrDebugPtr : Pointer = nil;
       OvrHeapOrg : Word = 0;
       OvrHeapPtr : Word = 0;
       OvrHeapEnd : Word = 0;
       OvrLoadList : Word = 0;
       OvrDosHandle : Word = 0;
       OvrEmsHandle : Word = $ffff;
       HeapOrg : Pointer absolute HeapBegin;
       HeapPtr : Pointer absolute HeapHigh;
       HeapEnd : Pointer = Pointer (High (PtrCard));
       FreeList : Pointer = nil;
       FreeZero : Pointer = nil;
       StackLimit : Word = 0;
       HeapList : Word = 0;
       HeapLimit : Word = 1024;
       HeapBlock : Word = 8192;
       HeapAllocFlags : Word = 2;
       CmdShow : Integer = 0;
       SaveInt00 : Pointer = nil;
       SaveInt02 : Pointer = nil;
       SaveInt0C : Pointer = nil;
       SaveInt0D : Pointer = nil;
       SaveInt1B : Pointer = nil;
       SaveInt21 : Pointer = nil;
       SaveInt23 : Pointer = nil;
       SaveInt24 : Pointer = nil;
       SaveInt34 : Pointer = nil;
       SaveInt35 : Pointer = nil;
       SaveInt36 : Pointer = nil;
       SaveInt37 : Pointer = nil;
       SaveInt38 : Pointer = nil;
       SaveInt39 : Pointer = nil;
       SaveInt3A : Pointer = nil;
       SaveInt3B : Pointer = nil;
       SaveInt3C : Pointer = nil;
       SaveInt3D : Pointer = nil;
       SaveInt3E : Pointer = nil;
       SaveInt3F : Pointer = nil;
       SaveInt75 : Pointer = nil;
       RealModeRegs : array [0 .. 49] of Byte =
         (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0);
     
     { Mostly useless BP compatible pointer functions }
     function  Ofs (const X) : PtrWord;
     function  Seg (const X) : PtrWord;
     function  Ptr (Seg, Ofs : PtrWord) : Pointer;
     function  CSeg : PtrWord;
     function  DSeg : PtrWord;
     function  SSeg : PtrWord;
     function  SPtr : PtrWord;
     
     {
       Routines to handle BP's 6 byte `Real' type which is formatted like
       this:
     
       47                                                   0
       -|------- -------- -------- -------- --------|--------
        |                                           |
        +----------+                   +------------+
       47 Sign Bit |  8..46 Mantissa   | 0..7 Biased Exponent
     
       This format does not support infinities, NaNs and denormalized
       numbers. The first digit after the binary point is not stored and
       assumed to be 1. (This is called the normalized representation of
       a binary floating point number.)
     
       In GPC, this type is represented by the type `BPReal' which is
       binary compatible to BP's type, and can therefore be used in
       connection with binary files used by BP programs.
     
       The functions `RealToBPReal' and `BPRealToReal' convert between
       this type and GPC's `Real' type. Apart from that, `BPReal' should
       be treated as opaque.
     
       The variables `BPRealIgnoreOverflow' and `BPRealIgnoreUnderflow'
       determine what to do in the case of overflows and underflows. The
       default values are BP compatible.
     }
     
     var
       { Ignore overflows, and use the highest possible value instead. }
       BPRealIgnoreOverflow  : Boolean = False;
     
       { Ignore underflows, and use 0 instead. This is BP's behaviour,
         but has the disadvantage of diminishing computation precision. }
       BPRealIgnoreUnderflow : Boolean = True;
     
     type
       BPReal = record
         Format : array [1 .. 6] of Cardinal (8)
       end;
     
     function RealToBPReal (R : Real) : BPReal;
     function BPRealToReal (const BR : BPReal) : Real;
     
     { Heap management stuff }
     
     const
       { Possible return values for HeapError }
       HeapErrorRunError = 0;
       HeapErrorNil      = 1;
       HeapErrorRetry    = 2;
     
     var
       { If assigned to a function, it will be called when memory
         allocations do not find enough free memory. Its return value
         determines if a run time error should be raised (the default),
         or nil should be returned, or the allocation should be retried
         (causing the routine to be called again if the allocation still
         doesn't succeed).
     
         Notes:
     
         - Returning nil can cause some routines of the RTS and units
           (shipped with GPC or third-party) to crash when they don't
           expect nil, so better don't use this mechanism, but rather
           CGetMem where needed.
     
         - Letting the allocation be retried, of course, only makes sense
           if the routine freed some memory before -- otherwise it will
           cause an infinite loop! So, a meaningful HeapError routine
           should dispose of some temporary objects, if available, and
           return HeapErrorRetry, and return HeapErrorRunError when no
           (more) of them are available.
       }
       HeapError : ^function (Size : Word) : Integer = nil;
     
     { Just returns HeapErrorNil. When this function is assigned to
       HeapError, GetMem and New will return a nil pointer instead of
       causing a runtime error when the allocation fails. See the comment
       for HeapError above. }
     function  HeapErrorNilReturn (Size : Word) : Integer;
     
     { Return the total free memory/biggest free memory block. Except
       under Win32 and DJGPP, these are expensive routines -- try to
       avoid them. Under Win32, MaxAvail returns the same as MemAvail, so
       don't rely on being able to allocate a block of memory as big as
       MaxAvail indicates. Generally it's preferable to not use these
       functions at all in order to do a safe allocation, but just try to
       allocate the memory needed using CGetMem, and check for a nil
       result. What makes these routines unrealiable is, e.g., that on
       multi-tasking systems, another process may allocate memory after
       you've called MemAvail/MaxAvail and before you get to do the next
       allocation. Also, please note that some systems over-commit
       virtual memory which may cause MemAvail to return a value larger
       than the actual (physical plus swap) memory available. Therefore,
       if you want to be "sure" (modulo the above restrictions) that the
       memory is actually available, use MaxAvail. }
     function  MemAvail : Cardinal;
     function  MaxAvail : Cardinal;


File: gpc,  Node: Trap,  Next: Turbo3,  Prev: System,  Up: GPC Units

7.13.17 Trap runtime errors
---------------------------

   The following listing contains the interface of the Trap unit.

   This unit allows you to trap runtime errors, so a runtime error will
not abort the program, but pass the control back to a point within the
program. Use with care, and read the notes in the interface, please.

     {
     Trapping runtime errors
     
     The Trap unit allows you to trap runtime errors, so a runtime error
     will not abort the program, but pass the control back to a point
     within the program.
     
     The usage is simple. The TrapExec procedure can be called with a
     function (p) as an argument. p must take a boolean argument. p will
     immediately be called with False given as its argument. When a
     runtime error would otherwise be caused while p is active, p will
     instead be called again with True as its argument. After p returns,
     runtime errors will not be trapped.
     
     When the program terminates (e.g. by reaching its end or by a Halt
     statement) and a runtime error was trapped during the run, Trap will
     set the ExitCode and ErrorAddr variables to indicate the trapped
     error.
     
     Notes:
     
     - After trapping a runtime error, your program might not be in a
       stable state. If the runtime error was a "minor" one (such as a
       range checking or arithmetic error), it should not be a problem.
       But if you e.g. write a larger application and use Trap to prevent
       a sudden abort caused by an unexpected runtime error, you should
       make the program terminate regularly as soon as possible after a
       trapped error (maybe telling the user to save the data, then
       terminate the program and report the error to you).
     
     - Since the trapping mechanism *jumps* back, it has all the negative
       effects that a (non-local!) `goto' can have! You should be aware
       of the consequences of all active procedures being terminated at
       an arbitrary point!
     
     Copyright (C) 1996-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     
     unit Trap;
     
     interface
     
     uses GPC;
     
     var
       TrappedExitCode : Integer = 0;
       TrappedErrorAddr : Pointer = nil;
       TrappedErrorMessageString : TString = '';
     
     procedure TrapExec (procedure p (Trapped : Boolean));


File: gpc,  Node: Turbo3,  Next: WinDos,  Prev: Trap,  Up: GPC Units

7.13.18 BP compatibility: Turbo3
--------------------------------

   The following listing contains the interface of the Turbo3 unit.

   This is a compatibility unit to BP's `Turbo3' compatibility unit to
TP3. ;-) It is not meant to be used in any newly written code.

     {
     Turbo Pascal 3.0 compatibility unit
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit Turbo3;
     
     interface
     
     uses GPC, System, CRT;
     
     var
       Kbd : Text;
       CBreak : Boolean absolute CheckBreak;
     
     procedure AssignKbd (var F : (*AnyFile*)Text);
     function  (*@@fjf260*)MemAvail3 : Integer;
     function  (*@@fjf260*)MaxAvail3 : Integer;
     function  LongFileSize (var F : AnyFile) : Real;
     function  LongFilePos  (var F : AnyFile) : Real;
     procedure LongSeek     (var F : AnyFile; aPosition : Real);
     procedure (*@@fjf260*)LowVideo3;
     procedure (*@@fjf260*)HighVideo3;


File: gpc,  Node: WinDos,  Prev: Turbo3,  Up: GPC Units

7.13.19 BP compatibility: WinDos
--------------------------------

   The following listing contains the interface of the WinDos unit.

   This is a portable implementation of most routines from BP's
`WinDos' unit. A few routines that are Dos - or even x86 real mode -
specific, are only available if `__BP_UNPORTABLE_ROUTINES__' is defined,
*Note BP Incompatibilities::.

   The same functionality and much more is available in the Run Time
System, *Note Run Time System::. The RTS routines usually have
different names and/or easier and less limiting interfaces (e.g.
`ReadDir' etc. vs. `FindFirst' etc.), and are often more efficient.

   Therefore, using this unit is not recommended in newly written
programs.

     {
     Mostly BP compatible portable WinDos unit
     
     This unit supports most, but not all, of the routines and
     declarations of BP's WinDos unit.
     
     NOTES:
     
     - The procedures GetIntVec and SetIntVec are not supported since
       they make only sense for Dos real-mode programs (and GPC compiled
       programs do not run in real-mode, even on x86 under Dos). The
       procedures Intr and MsDos are only supported under DJGPP if
       `__BP_UNPORTABLE_ROUTINES__' is defined (with the
       `-D__BP_UNPORTABLE_ROUTINES__' option). A few other routines are
       also only supported with this define, but on all platforms (but
       they are crude hacks, that's why they are not supported without
       this define).
     
     - The internal structure of file variables (TFileRec and TTextRec)
       is different in GPC. However, as far as TFDDs are concerned, there
       are other ways to achieve the same in GPC, see the GPC unit.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Author: Frank Heckenbach <frank@pascal.gnu.de>
     
     This file is part of GNU Pascal.
     
     GNU Pascal is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, or (at your option)
     any later version.
     
     GNU Pascal is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with GNU Pascal; see the file COPYING. If not, write to the
     Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
     02111-1307, USA.
     
     As a special exception, if you link this file with files compiled
     with a GNU compiler to produce an executable, this does not cause
     the resulting executable to be covered by the GNU General Public
     License. This exception does not however invalidate any other
     reasons why the executable file might be covered by the GNU General
     Public License.
     }
     
     {$gnu-pascal,B-,I-}
     
     unit WinDos;
     
     interface
     
     uses GPC, System, Dos;
     
     const
       { File attribute constants }
       faReadOnly  = ReadOnly;
       faHidden    = Hidden;    { set for dot files except `.' and `..' }
       faSysFile   = SysFile;   { not supported }
       faVolumeID  = VolumeID;  { not supported }
       faDirectory = Directory;
       faArchive   = Archive;   { means: not executable }
       faAnyFile   = AnyFile;
     
       { Maximum file name component string lengths }
       fsPathName  = 79;
       fsDirectory = 67;
       fsFileName  = 8;
       fsExtension = 4;
     
       { FileSplit return flags }
       fcExtension = 1;
       fcFileName  = 2;
       fcDirectory = 4;
       fcWildcards = 8;
     
       { Flag bit masks -- only used by the unportable Dos routines }
       FCarry     = 1;
       FParity    = 4;
       FAuxiliary = $10;
       FZero      = $40;
       FSign      = $80;
       FOverflow  = $800;
     
     type
       PTextBuf = ^TTextBuf;
       TTextBuf = TextBuf;
     
       { Search record used by FindFirst and FindNext }
       TSearchRec = {$ifdef __BP_TYPE_SIZES__} packed {$endif} record
          Fill : SearchRecFill;
          Attr : Byte8;
          Time, Size : LongInt;
          Name : {$ifdef __BP_TYPE_SIZES__}
                 packed array [0 .. 12] of Char
                 {$else}
                 TStringBuf
                 {$endif};
          Reserved : SearchRec
       end;
     
       { Date and time record used by PackTime and UnpackTime }
       TDateTime = DateTime;
     
       { 8086 CPU registers -- only used by the unportable Dos routines }
       TRegisters = Registers;
     
     var
       { Error status variable }
       DosError : Integer; external;
     
     procedure GetDate (var Year, Month, Day, DayOfWeek : Word);
       asmname '_p_getdate';
     procedure GetTime (var Hour, Minute, Second, Sec100 : Word);
       asmname '_p_gettime';
     procedure (*@@fjf260*)WGetCBreak (var BreakOn : Boolean);
       asmname '_p_getcbreak';
     procedure (*@@fjf260*)WSetCBreak (BreakOn : Boolean);
       asmname '_p_setcbreak';
     procedure (*@@fjf260*)WGetVerify (var VerifyOn : Boolean);
       asmname '_p_getverify';
     procedure (*@@fjf260*)WSetVerify (VerifyOn : Boolean);
       asmname '_p_setverify';
     function  DiskFree (Drive : Byte) : LongInt; asmname '_p_diskfree';
     function  DiskSize (Drive : Byte) : LongInt; asmname '_p_disksize';
     procedure GetFAttr (var F : GPC_AnyFile; var Attr : Word);
       asmname '_p_getfattr';
     procedure SetFAttr (var F : GPC_AnyFile; Attr : Word);
       asmname '_p_setfattr';
     procedure GetFTime (var F : GPC_AnyFile; var aTime : LongInt);
       asmname '_p_getftime';
     procedure SetFTime (var F : GPC_AnyFile; aTime : LongInt);
       asmname '_p_setftime';
     
     { FindFirst and FindNext are quite inefficient since they emulate
       all the brain-dead Dos stuff. If at all possible, the standard
       routines OpenDir, ReadDir and CloseDir (in the GPC unit) should be
       used instead. }
     procedure (*@@fjf260*)WFindFirst (Path : PChar; Attr : Word; var
       SR : TSearchRec);
     procedure (*@@fjf260*)WFindNext  (var SR : TSearchRec);
     
     procedure (*@@fjf260*)WFindClose (var SR : TSearchRec);
     procedure UnpackTime (P : LongInt; var T : TDateTime);
       asmname '_p_unpacktime';
     procedure PackTime (const T : TDateTime; var P : LongInt);
       asmname '_p_packtime';
     function  FileSearch (Dest, Name, List : PChar) : PChar;
     function  FileExpand (Dest, Name : PChar) : PChar;
     function  FileSplit (Path, Dir, Name, Ext : PChar) : Word;
     function  GetCurDir (Dir : PChar; Drive : Byte) : PChar;
     procedure SetCurDir (Dir : PChar);
     procedure CreateDir (Dir : PChar);
     procedure RemoveDir (Dir : PChar);
     function  GetArgCount : Integer;
     function  GetArgStr (Dest : PChar; ArgIndex : Integer; MaxLen :
       Word) : PChar;
     function  GetEnvVar (VarName : PChar) : PChar;
       asmname '_p_cstringgetenv';
     
     {$ifdef __BP_UNPORTABLE_ROUTINES__}
     {$ifdef DJGPP}
     procedure (*@@fjf260*)WIntr (IntNo : Byte; var Regs : Registers);
       asmname '_p_intr';
     procedure (*@@fjf260*)WMsDos (var Regs : Registers);
       asmname '_p_msdos';
     {$endif}
     function  (*@@fjf260*)WDosVersion : Word; asmname '_p_dosversion';
     procedure (*@@fjf260*)WSetDate (Year, Month, Day : Word);
       asmname '_p_setdate';
     procedure (*@@fjf260*)WSetTime (Hour, Minute, Second, Sec100 :
       Word); asmname '_p_settime';
     {$endif}


File: gpc,  Node: Reference,  Next: Keywords,  Prev: Programming,  Up: Top

8 The Alphabetical GPC Language Reference
*****************************************

   *This chapter is still under development. All identifiers are
listed, but not all with explanations.*

   This chapter contains an alphabetical list of all built-in
identifiers of the GNU Pascal compiler. For detailed and comprehensive
description of syntax and reserved words, see *Note Programming::. This
chapter explains only built-in procedures and functions in detail. It
does not cover extensions provided by external units and libraries
which are supposed to come with their own documentation.

* Menu:

* Abs::
* absolute::
* abstract::
* Addr::
* AlignOf::
* all::
* and::
* and then::
* and_then::
* AnsiChar::
* Append::
* ArcTan::
* Arg::
* array::
* asm::
* asmname::
* Assign::
* Assigned::
* attribute::
* begin::
* Bind::
* bindable::
* Binding::
* BindingType::
* BitSizeOf::
* BlockRead::
* BlockWrite::
* Boolean::
* Break::
* Byte::
* ByteBool::
* ByteCard::
* ByteInt::
* C::
* Card::
* Cardinal::
* case::
* Char::
* ChDir::
* Chr::
* C_Language::
* class::
* Close::
* Cmplx::
* Comp::
* Complex::
* Concat::
* Conjugate::
* const::
* constructor::
* Continue::
* Copy::
* Cos::
* CString::
* CString2String::
* CStringCopyString::
* Date::
* Dec::
* DefineSize::
* Delete::
* destructor::
* Dispose::
* div::
* do::
* Double::
* downto::
* else::
* Empty::
* end::
* EOF::
* EOLn::
* EpsReal::
* Eq::
* Erase::
* Exclude::
* Exit::
* Exp::
* export::
* exports::
* Extend::
* Extended::
* extern::
* external::
* Fail::
* False::
* far::
* file::
* FileMode::
* FilePos::
* FileSize::
* FillChar::
* Flush::
* for::
* forward::
* Frac::
* FrameAddress::
* FreeMem::
* function::
* GE::
* Get::
* GetMem::
* GetTimeStamp::
* goto::
* GT::
* Halt::
* High::
* if::
* Im::
* implementation::
* import::
* in::
* Inc::
* Include::
* Index::
* inherited::
* inline::
* InOutRes::
* InOutResStr::
* Input::
* Insert::
* Int::
* Integer::
* interface::
* interrupt::
* IOResult::
* is::
* label::
* LastPosition::
* LE::
* Length::
* library::
* Ln::
* LoCase::
* LongBool::
* LongCard::
* LongestBool::
* LongestCard::
* LongestInt::
* LongestReal::
* LongestWord::
* LongInt::
* LongReal::
* LongWord::
* Low::
* LT::
* Mark::
* Max::
* MaxChar::
* MaxInt::
* MaxReal::
* MedBool::
* MedCard::
* MedInt::
* MedReal::
* MedWord::
* Min::
* MinReal::
* MkDir::
* mod::
* module::
* Move::
* MoveLeft::
* MoveRight::
* Name::
* NE::
* near::
* New::
* NewCString::
* nil::
* not::
* Null::
* object::
* Odd::
* of::
* only::
* operator::
* or::
* or else::
* Ord::
* or_else::
* otherwise::
* Output::
* Override::
* Pack::
* packed::
* Page::
* PAnsiChar::
* ParamCount::
* ParamStr::
* PChar::
* Pi::
* Pointer::
* Polar::
* Pos::
* Position::
* pow::
* Pred::
* private::
* procedure::
* program::
* property::
* protected::
* PtrCard::
* PtrDiffType::
* PtrInt::
* PtrWord::
* public::
* published::
* Put::
* qualified::
* Random::
* Randomize::
* Re::
* Read::
* ReadLn::
* ReadStr::
* Real::
* record::
* register::
* Release::
* Rename::
* repeat::
* Reset::
* resident::
* restricted::
* Result::
* Return::
* ReturnAddress::
* Rewrite::
* RmDir::
* Root::
* Round::
* RunError::
* Seek::
* SeekRead::
* SeekUpdate::
* SeekWrite::
* segment::
* Self::
* set::
* SetFileTime::
* SetLength::
* SetType::
* shl::
* ShortBool::
* ShortCard::
* ShortInt::
* ShortReal::
* ShortWord::
* shr::
* Sin::
* Single::
* SizeOf::
* SizeType::
* SmallInt::
* Sqr::
* SqRt::
* StandardError::
* StandardInput::
* StandardOutput::
* static::
* StdErr::
* Str::
* String::
* String2CString::
* SubStr::
* Succ::
* Text::
* TextWritable::
* then::
* Time::
* TimeStamp::
* to::
* to begin do::
* to end do::
* Trim::
* True::
* Trunc::
* Truncate::
* type::
* type of::
* TypeOf::
* UnBind::
* unit::
* Unpack::
* until::
* UpCase::
* Update::
* uses::
* Val::
* value::
* var::
* view::
* virtual::
* Void::
* volatile::
* while::
* with::
* Word::
* WordBool::
* Write::
* WriteLn::
* WriteStr::
* xor::


File: gpc,  Node: Abs,  Next: absolute,  Up: Reference

Abs
===

Synopsis
--------

     function Abs (i: INTEGER TYPE): INTEGER TYPE;
   or
     function Abs (x: REAL TYPE): REAL TYPE;
   or
     function Abs (z: COMPLEX TYPE): REAL TYPE;

Description
-----------

   Returns the absolute value of the argument. For integer or real
values of `x', the definition is

     function Abs (x: INTEGER OR REAL TYPE): INTEGER OR REAL TYPE;
     begin
       if x < 0 then
         Abs := -x
       else
         Abs := x
     end;

whereas for complex values it is

     function Abs (x: Complex): Real;
     begin
       Abs := SqRt (x * Conjugate (x))
     end;

Conforming to
-------------

   The function `Abs' is defined in ISO-7185 Standard Pascal; its
application to complex values is defined in ISO-10206 Extended Pascal.

Example
-------

     program AbsDemo;
     var
       i1: Complex;
     begin
       WriteLn (Abs (42));             { 42 }
       WriteLn (Abs (-42));            { 42 }
       WriteLn (Abs (-12.1) : 0 : 1);  { 12.1 }
       i1 := Cmplx (1, 1);             { 1 + i }
       WriteLn (Abs (i1) : 0 : 3)      { 1.414, i.e. SqRt (2) }
     end.

See also
--------

   *Note Sqr::.


File: gpc,  Node: absolute,  Next: abstract,  Prev: Abs,  Up: Reference

absolute
========

Synopsis
--------

     var
       VARIABLE NAME: DATA TYPE absolute VARIABLE REFERENCE;
   or
     var
       VARIABLE NAME: DATA TYPE absolute INTEGER EXPRESSION;

Description
-----------

   The first meaning of the `absolute' directive allows to put a
variable to the address of another one and thus provides a type-casting
mechanism.

   In most cases, VARIABLE REFERENCE will be just a variable name, but
GPC also allows arbitrary pointer expressions here. If VARIABLE
REFERENCE has neither a constant address nor is a variable parameter,
GPC prints a warning. This warning is suppressed in "extended syntax"
mode which is switched on by the `--extended-syntax' option or the
`{$X+}' compiler directive.

   GPC also allows explicit type casts. Variant records (as defined in
ISO-7185 Standard Pascal), however, have no _guaranteed_ overlaying and
are therefore _not_ suitable for type casts.

   The second meaning of `absolute' places a variable at a specified
address. This is useful on machines without virtual memory addressing
for doing certain low-level operations, but should be avoided on
systems with memory protection such as Unix-like systems.  GPC does not
check whether the specified virtual address makes any sense and does
not provide a built-in mechanism to map it to a real address.

   GPC warns about this second use of `absolute' unless "extended
syntax" has been requested.

Conforming to
-------------

   `absolute' is a Borland Pascal extension.

   Borland Pascal has a slightly different syntax for the second
meaning related to the addressing scheme of Intel x86 processors
working in real mode.

   Allowing arbitrary memory references instead of just variable names
in the first meaning of `absolute' is a GNU Pascal extension.

Example
-------

     program AbsoluteDemo;
     
     {$X+}
     
     const
       IOMem = $f0000000;
     
     var
       Mem: array [0 .. High (Cardinal)] of Byte absolute 0;
     
       { This address has no actual meaning }
       MyPort: Byte absolute IOMem + $c030;
     
     { Beware: Using any of the variables above will crash
       your program unless you know exactly what you do!
       That's why GPC warns about it without the $X+ directive. }
     
     var
       x: Real;
       a: array [1 .. SizeOf (Real)] of Byte absolute x;
       i: Integer;
       b: Byte absolute a [i];  { GNU extension: non-constant memory reference. }
     
     begin
       x := 3.14;
     
       { Look at the internal representation of a real variable. }
       for i := 1 to SizeOf (Real) do
         Write (a [i] : 4);
       WriteLn;
     
       { The same again, more ugly... }
       for i := 1 to SizeOf (Real) do
         Write (b : 4);
       WriteLn;
     
       { And yes, there's an even more ugly way to do it... }
       for i := 1 to SizeOf (Real) do
         Write (Mem [PtrCard (@x) + i - 1] : 4);
       WriteLn
     end.

See also
--------

   *Note record::, *Note Type Casts::.


File: gpc,  Node: abstract,  Next: Addr,  Prev: absolute,  Up: Reference

abstract
========

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Addr,  Next: AlignOf,  Prev: abstract,  Up: Reference

Addr
====

Synopsis
--------

     function Addr (const Foo): Pointer;

Description
-----------

   `Addr' returns the address of its argument. It is equivalent to the
address operator and provided for compatibility with Borland Pascal
which in turn implements it for backward-compatibility with Turbo
Pascal.

Conforming to
-------------

   `Addr' is a Borland Pascal extension.

Example
-------

     program AddrDemo;
     var
       Foo: ^Integer;
       Bar: Integer;
     begin
       Foo := Addr (Bar);  { Let `Foo' point to `Bar'. }
       Bar := 17;
       Foo^ := 42;  { Change the value of `Bar' to 42 }
       WriteLn (Bar)
     end.

See also
--------

   *Note Operators::.


File: gpc,  Node: AlignOf,  Next: all,  Prev: Addr,  Up: Reference

AlignOf
=======

Synopsis
--------

     function AlignOf (var x): Integer;

Description
-----------

   Returns the alignment of a type or variable in bytes.

Conforming to
-------------

   `AlignOf' is a GNU extension.

Example
-------

     program AlignOfDemo;
     var
       a: Integer;
       b: array [1 .. 8] of Char;
     begin
       WriteLn (AlignOf (a));  { Alignment of `Integer'; usually 4 bytes. }
       WriteLn (AlignOf (b));  { Alignment of `Char'; usually 1 byte. }
     end.

   Although the array is bigger than a single char, it is accessed char
by char, so there usually is no need to align it on a 4 byte boundary
or such.  (This may be false on some platforms.)

See also
--------

   *Note SizeOf::, *Note BitSizeOf::, *Note TypeOf::.


File: gpc,  Node: all,  Next: and,  Prev: AlignOf,  Up: Reference

all
===

Synopsis
--------

     export foo = all;

Description
-----------

   `all' is a predefined export interface for Extended Pascal modules.
You can use it to export all identifiers declared in an interface module
automatically.

Conforming to
-------------

   `All' is a GNU extension.

Example
-------

     program AllDemo;
     
     import AllInterface in 'allmodule.pas';
     
     begin
       Bar (a);
       WriteLn (b)
     end.

     module AllModule interface;
     
     export
       AllInterface = all;  { Same as `AllInterface = (a, b, Bar);' }
     
     var
       a, b: Integer;
     
     procedure Bar (i: Integer);
     
     end.
     
     module AllModule implementation;
     
     procedure Bar (i: Integer);
     begin
       b := a
     end;
     
     to begin do
       a := 42;
     
     end.

See also
--------

   *Note Modules::.


File: gpc,  Node: and,  Next: and then,  Prev: all,  Up: Reference

and
===

Synopsis
--------

     operator and (operand1, operand2: Boolean) = Result: Boolean;
   or
     operator and (operand1, operand2: INTEGER TYPE) = Result: INTEGER TYPE;
   or
     procedure and (var operand1: INTEGER TYPE; operand2: INTEGER TYPE);

Description
-----------

   In GNU Pascal, `and' has three built-in meanings:

  1. Logical "and" between two `Boolean'-type expressions.  The result
     of the operation is of `Boolean' type.

     By default, `and' acts as a short-circuit operator in GPC:  If the
     first operand is `False', the second operand is not evaluated
     because the result is already known to be `False'. You can change
     this to complete evaluation using the `--no-short-circuit'
     command-line option or the `{$B+}' compiler directive.

  2. Bitwise "and" between two integer-type expressions.  The result is
     of the common integer type of both expressions.

  3. Use as a "procedure":  `operand1' is "and"ed bitwise with
     `operand2'; the result is stored in `operand1'.


Conforming to
-------------

   The logical `and' operator is defined in ISO-7185 Standard Pascal.

   According to ISO, you cannot rely on `and' being a short-circuit
operator.  On the other hand, GPC's default behaviour does _not_
contradict the ISO standard.  (See *Note and_then::.)  However, since
it seems to be a de-facto standard among ISO Pascal compilers to
evaluate both operands of `and', GPC switches to `--no-short-circuit'
mode if one of the language dialect options selecting ISO Pascal, for
instance `--extended-pascal', is given.  Use `--short-circuit' to
override.

   Use of `and' as a bitwise operator for integers is a Borland Pascal
extension.

   Use of `and' as a "procedure" is a GNU extension.

Example
-------

     program AndDemo;
     var
       a, b, c: Integer;
     begin
       if (a = 0) and (b = 0) then  { logical `and' }
         c := 1
       else if a and b = 0 then  { bitwise `and' }
         c := 2
       else
         and (c, a)  { same as `c := c and a' }
     end.

   Note the difference between the logical `and' and the bitwise `and':
When `a' is 2 and `b' is 4, then `a and b' is 0.  *Beware:*  `a and b
= 0' has nothing to do with `(a = 0) and (b = 0)'!

   Since bitwise `and' has a higher priority than the `=' operator,
parentheses are needed in `if (a = 0) and (b = 0)' because otherwise `0
and b' would be calculated first, and the remainder would cause a parse
error.

See also
--------

   *Note and_then::, *Note and then::, *Note or::, *Note xor::, *Note
Operators::.


File: gpc,  Node: and then,  Next: and_then,  Prev: and,  Up: Reference

and then
========

Synopsis
--------

     { `and then' is built in. A user-defined operator cannot consist of
        two words. }
     operator and then (operand1, operand2: Boolean) = Result: Boolean;

Description
-----------

   `and then' is an alias for the short-circuit logical operator
`and_then'.

Conforming to
-------------

   While `and_then' is defined in ISO-10206 Extended Pascal, `and then'
is a GNU Extension.

Example
-------

     program AndThenDemo;
     var
       p: ^Integer;
     begin
       New (p);
       ReadLn (p^);
       if (p <> nil) and then (p^ < 42) then  { This is safe. }
         WriteLn (p^, ' is less than 42')
     end.

See also
--------

   *Note and_then::, *Note and::, *Note or else::.


File: gpc,  Node: and_then,  Next: AnsiChar,  Prev: and then,  Up: Reference

and_then
========

Synopsis
--------

     operator and_then (operand1, operand2: Boolean) = Result: Boolean;

Description
-----------

   The `and_then' short-circuit logical operator performs the same
operation as the logical operator `and'.  But while the ISO standard
does not specify anything about the evaluation of the operands of `and'
- they may be evaluated in any order, or not at all - `and_then' has a
well-defined behaviour:  It evaluates the first operand.  If the result
is `False', `and_then' returns `False' without evaluating the second
operand.  If it is `True', the second operand is evaluated and returned.

   Since the behaviour described above is the most efficient way to
implement `and', GPC by default treats `and' and `and_then' exactly the
same.  If you want, for some reason, to have both operands of `and'
evaluated completely, you must assign both to temporary variables and
then use `and' - or `and_then', it does not matter.

Conforming to
-------------

   `and_then' is an ISO-10206 Extended Pascal extension.

   Some people think that the ISO standard requires both operands of
`and' to be evaluated.  This is false.  What the ISO standard _does_
say is that you cannot rely on a certain order of evaluation of the
operands of `and'; in particular things like the following program can
crash according to ISO Pascal, although they cannot crash when compiled
with GNU Pascal running in default mode.

     program AndBug;
     var
       p: ^Integer;
     begin
       New (p);
       ReadLn (p^);
       if (p <> nil) and (p^ < 42) then  { This is NOT safe! }
         WriteLn ('You''re lucky. But the test could have crashed...')
     end.

Example
-------

     program And_ThenDemo;
     var
       p: ^Integer;
     begin
       New (p);
       ReadLn (p^);
       if (p <> nil) and_then (p^ < 42) then  { This is safe. }
         WriteLn (p^, ' is less than 42')
     end.

See also
--------

   *Note and then::, *Note and::, *Note or_else::.


File: gpc,  Node: AnsiChar,  Next: Append,  Prev: and_then,  Up: Reference

AnsiChar
========

Synopsis
--------

     type
       AnsiChar = Char;

Description
-----------

   `AnsiChar' is an 8 bit char type. Currently, it is the same as
`Char', but this might change in the future, once `wide chars' (16 bit
chars) will be introduced into GPC. Depending on the platform, `Char'
might be either `AnsiChar' or `WideChar' then.

Conforming to
-------------

   `AnsiChar' is a Borland Delphi extension.

Example
-------

     program AnsiCharDemo;
     var
       A: AnsiChar;  { There is nothing special with `AnsiChar'. }
       B: Char;
     begin
       A := 'A';
       A := B
     end.

See also
--------

   *Note PAnsiChar::, *Note Char::.


File: gpc,  Node: Append,  Next: ArcTan,  Prev: AnsiChar,  Up: Reference

Append
======

Synopsis
--------

     procedure Append (var F: ANY FILE; [name: String;]
                                              [blocksize: Cardinal]);

Description
-----------

   `Append' opens a file for writing.  If the file does not exist, it
is created.  If it does exist, the file pointer is positioned after the
last element.

   Like `Rewrite' and `Reset' do, `Append' accepts an optional second
and third parameter for the name of the file in the filesystem and, for
untyped files, the block size of the file. (For details, see *Note
Rewrite::.)

Conforming to
-------------

   `Append' is a Borland Pascal extension. ISO-10206 Extended Pascal
has *Note Extend:: instead.

Example
-------

     program AppendDemo;
     var
       Sample: Text;
     begin
       Assign (Sample, 'sample.txt');
       Rewrite (Sample);
       WriteLn (Sample, 'Hello, World!');  { `sample.txt' now has one line }
       Close (Sample);
     
       { ... }
     
       Append (Sample);
       WriteLn (Sample, 'Hello again!');   { `sample.txt' now has two lines }
       Close (Sample)
     end.

See also
--------

   *Note Assign::, *Note Reset::, *Note Rewrite::, *Note Update::,
*Note Extend::.


File: gpc,  Node: ArcTan,  Next: Arg,  Prev: Append,  Up: Reference

ArcTan
======

Synopsis
--------

     function ArcTan (x: Real): Real;
   or
     function ArcTan (z: Complex): Complex;

Description
-----------

   `ArcTan' returns the (principal value of the) arcus tangent of the
argument. The result is in the range `-pi / 2 < ArcTan (x) < pi / 2'
for real arguments.

Conforming to
-------------

   The function `ArcTan' is defined in ISO-7185 Standard Pascal; its
application to complex values is defined in ISO-10206 Extended Pascal.

Example
-------

     program ArcTanDemo;
     begin
       { yields 3.14159 as ArcTan (1) = Pi / 4 }
       WriteLn (4 * ArcTan (1) : 0 : 5)
     end.

See also
--------

   *Note Sin::, *Note Cos::, *Note Ln::, *Note Arg::.


File: gpc,  Node: Arg,  Next: array,  Prev: ArcTan,  Up: Reference

Arg
===

Synopsis
--------

     function Arg (z: Complex): Real;

Description
-----------

   `Arg' returns the complex "argument", i.e. the angle (in radian) in
the complex plane with respect to the real axis, of its parameter `z'.
The result is in the range of `-Pi < Arg (z) <= Pi'.

Conforming to
-------------

   `Arg' is an ISO-10206 Extended Pascal extension.

Example
-------

     program ArgDemo;
     var
       z: Complex;
     begin
       z := Cmplx (1, 1);  { 1 + i }
       WriteLn (Arg (z) : 0 : 5)  { yields 0.78540, i.e. Pi / 4 }
     end.

See also
--------

   *Note ArcTan::, *Note Ln::, *Note Polar::.


File: gpc,  Node: array,  Next: asm,  Prev: Arg,  Up: Reference

array
=====

Synopsis
--------

   In type definitions:
     array [INDEX TYPE] of ELEMENT TYPE
   or
     array [INDEX TYPE, ..., INDEX TYPE] of ELEMENT TYPE

   In parameter list declarations:
     array of ELEMENT TYPE

Description
-----------

   The reserved word `array' is used to define an array type.

   @@!!!! arrays in parameter lists

Conforming to
-------------

   Array types are defined in ISO 7185 Standard Pascal.

Example
-------

     program ArrayDemo;
     type
       IntArray = array [1 .. 20] of Integer;
       WeekDayChars = array [(Mon, Tue, Wed, Thu, Fri, Sat, Sun)] of Char;
       Foo = array [0 .. 9, 'a' .. 'z', (Baz, Glork1, Fred)] of Real;
       TwoDimIntArray = array [1 .. 10] of IntArray;
       { is equivalent to: }
       TwoDimIntArray2 = array [1 .. 10, 1 .. 20] of Integer;
     
     procedure PrintChars (F: array of Char);
     var
       i: Integer;
     begin
       for i := Low (F) to High (F) do
         WriteLn (F [i])
     end;
     
     var
       Waldo: WeekDayChars;
     
     begin
       Waldo := 'HiWorld';
       PrintChars (Waldo)
     end.

See also
--------

   *Note Array Types::, *Note High::, *Note Low::


File: gpc,  Node: asm,  Next: asmname,  Prev: array,  Up: Reference

asm
===

   (Under construction.)

Synopsis
--------

Description
-----------

   See
`ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/contrib/gpcasm.zip'.

Conforming to
-------------

   `asm', as implemented in GPC, is a GNU extension. It is mostly
compatible to GCC's `asm', but not compatible to that of Borland Pascal.

Example
-------

See also
--------

   *Note Importing Libraries from Other Languages::, *Note asmname::


File: gpc,  Node: asmname,  Next: Assign,  Prev: asm,  Up: Reference

asmname
=======

Synopsis
--------

   PROCEDURE/FUNCTION HEADER; asmname NAME;

   or

   VARIABLE DECLARATION; asmname NAME;

Description
-----------

   The `asmname' directive declares the external name of a procedure,
function or variable. The external name of the routine is given
explicitly as a case-sensitive string constant. This is useful when
interfacing with libraries written in other languages.

   With this extension it is possible to access all external functions,
for example the X11 interface functions, and not only those written in
lowercase.

   The idea to use `external' for this purpose (to avoid name space
pollution) conflicts with another Borland extension not yet
implemented: In Borland Pascal, the declaration
     procedure Foo; external 'MyLib';
   means that the procedure Foo should be imported by name (`Foo') from
a dynamic link library `mylib.dll'.

Conforming to
-------------

   `asmname' is a GNU Pascal extension.

Example
-------

     program AsmnameDemo;
     
     { Make two variables aliases of each other by using `asmname'.
       This is not good style. If you must have aliases for any reason,
       `absolute' declaration may be the lesser evil... }
     var
       Foo: Integer; asmname 'Foo_Bar';
       Bar: Integer; asmname 'Foo_Bar';
     
     { A function from the C library }
     function PutS (Str: CString): Integer; asmname 'puts'; external;
     
     var
       Result: Integer;
     begin
       Result := PutS ('Hello World!');
       WriteLn ('puts wrote ', Result, ' characters (including a newline).');
       Foo := 42;
       WriteLn ('Foo = ', Foo);
       Bar := 17;
       WriteLn ('Setting Bar to 17.');
       WriteLn ('Now, Foo = ', Foo, '!!!')
     end.

See also
--------

   *Note C::, *Note C_Language::, *Note external::, *Note Importing
Libraries from Other Languages::.


File: gpc,  Node: Assign,  Next: Assigned,  Prev: asmname,  Up: Reference

Assign
======

   (Under contruction.)

Synopsis
--------

     procedure Assign (var F: ANY FILE; FileName: String);

Description
-----------

Conforming to
-------------

   `Assign' is a Borland Pascal extension.

Example
-------

See also
--------

   *Note Reset::, *Note Rewrite::, *Note Update::, *Note Extend::,
*Note Append::.


File: gpc,  Node: Assigned,  Next: attribute,  Prev: Assign,  Up: Reference

Assigned
========

   (Under construction.)

Synopsis
--------

     function Assigned (p: Pointer): Boolean;
   or
     function Assigned (p: PROCEDURAL TYPE): Boolean;

Description
-----------

   The `Assigned' function returns `True' if the pointer parameter or
the address of the procedural parameter is not `nil'; it returns
`False' if it is `nil'.

Conforming to
-------------

   `Assigned' is a Borland Pascal extension.

Example
-------

     program AssignedDemo;
     type
       PInt = ^Integer;
     
     procedure TellIfOdd (p: PInt);
     begin
       if Assigned (p) and then Odd (p^) then
         WriteLn ('The pointer p points to an odd value.')
     end;
     
     var
       foo: Integer;
     begin
       TellIfOdd (nil);
       foo := 1;
       TellIfOdd (@foo);
       foo := 2;
       TellIfOdd (@foo)
     end.

See also
--------

   *Note Null::, *Note nil::, *Note Pointer::.


File: gpc,  Node: attribute,  Next: begin,  Prev: Assigned,  Up: Reference

attribute
=========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

   `attribute' is a GNU Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: begin,  Next: Bind,  Prev: attribute,  Up: Reference

begin
=====

Synopsis
--------

     begin
       STATEMENT;
       STATEMENT;
       ...
       STATEMENT
     end;

Description
-----------

   The reserved word `begin' opens a `begin ... end' statement which
joins several STATEMENTS to one compound statement.

Conforming to
-------------

   `begin' is defined in ISO 7185 Standard Pascal

Example
-------

     program BeginDemo;
     begin
       if True then
         WriteLn ('single statement');
       if True then
         begin                     { clamp statement1 ... }
           WriteLn ('statement1');
           WriteLn ('statement2')
         end                       { ... to statement2 }
     end.

See also
--------

   *Note begin end Compound Statement::, *Note end::


File: gpc,  Node: Bind,  Next: bindable,  Prev: begin,  Up: Reference

Bind
====

   (Under construction.)

Synopsis
--------

     procedure Bind (var F: ANY FILE; B: BindingType);

Description
-----------

Conforming to
-------------

   `Bind' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: bindable,  Next: Binding,  Prev: Bind,  Up: Reference

bindable
========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

   `bindable' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Binding,  Next: BindingType,  Prev: bindable,  Up: Reference

Binding
=======

   (Under construction.)

Synopsis
--------

     function Binding (F: ANY FILE): BindingType;

Description
-----------

Conforming to
-------------

   `Binding' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: BindingType,  Next: BitSizeOf,  Prev: Binding,  Up: Reference

BindingType
===========

   (Under construction.)

Synopsis
--------

     type
       UnixTimeType = LongInt;
       BindingType = {@@packed} record
         Bound             : Boolean;
         Force             : Boolean;      { Can be set to allow binding to
                                             directories or inaccessible files }
         Extensions_Valid  : Boolean;
         Readable          : Boolean;
         Writable          : Boolean;
         Executable        : Boolean;
         Existing          : Boolean;      { Binding points to an existing file }
         Directory         : Boolean;      { Binding points to an existing
                                             directory; Existing is False then }
         Special           : Boolean;      { Binding points to an existing
                                             special file (device, pipe, socket,
                                             etc.); `Existing' is False then }
         SymLink           : Boolean;      { Binding points to a symbolic link }
         AccessTime,                       { Time of last access }
         ModificationTime,                 { Time of last modification }
         ChangeTime        : UnixTimeType; { Time of last change }
         User,                             { User ID of owner }
         Group,                            { Group ID of owner }
         Mode,                             { Access permissions, cf. ChMod }
         Device,                           { Device the file is on }
         INode             : Integer;      { Unix INode number }
         TextBinary        : Boolean;      { Open a Text file in binary mode }
         Handle            : Integer;      { Can be set to bind a Pascal file to
                                             a given file handle }
         Name              : String (Binding_Name_Length)
       end;

   (@@ Currently, in GPC, BindingType is not actually packed.)

   The fields `Bound' and `Name' are required by Extended Pascal.

   `Binding_Name_Length' is an implementation-defined constant.

Description
-----------

Conforming to
-------------

   `BindingType' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: BitSizeOf,  Next: BlockRead,  Prev: BindingType,  Up: Reference

BitSizeOf
=========

Synopsis
--------

     function BitSizeOf (var x): SizeType;

Description
-----------

   Returns the size of a type or variable in bits.

Conforming to
-------------

   `BitSizeOf' is a GNU Pascal extension.

Example
-------

     program BitSizeOfDemo;
     var
       a: Integer;
       b: array [1 .. 8] of Char;
       c: Integer (12);
       d: packed record
            x: Integer (12);
            y: 0 .. 3
          end;
     begin
       WriteLn (BitSizeOf (a));    { Size of an `Integer'; usually 32 bits. }
       WriteLn (BitSizeOf (b));    { Size of eight `Char's; usually 64 bits. }
       WriteLn (BitSizeOf (c));    { e.g. 16 bits (smallest addressable space). }
       WriteLn (BitSizeOf (d));    { e.g. 16 }
       WriteLn (BitSizeOf (d.x));  { 12 }
       WriteLn (BitSizeOf (d.y))   {  2 }
     end.

See also
--------

   *Note SizeOf::, *Note AlignOf::, *Note TypeOf::.


File: gpc,  Node: BlockRead,  Next: BlockWrite,  Prev: BitSizeOf,  Up: Reference

BlockRead
=========

   (Under construction.)

Synopsis
--------

     procedure BlockRead (var F: File; var Buffer; Blocks: Integer);
   or
     procedure BlockRead (var F: File; var Buffer; Blocks: Integer;
                          var BlocksRead: Integer);

Description
-----------

Conforming to
-------------

   `BlockRead' is an UCSD Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: BlockWrite,  Next: Boolean,  Prev: BlockRead,  Up: Reference

BlockWrite
==========

   (Under construction.)

Synopsis
--------

     procedure BlockWrite (var F: File; const Buffer; Blocks: Integer);
   or
     procedure BlockWrite (var F: File; const Buffer; Blocks: Integer;
                           var BlocksWritten: Integer);

Description
-----------

Conforming to
-------------

   `BlockWrite' is an UCSD Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Boolean,  Next: Break,  Prev: BlockWrite,  Up: Reference

Boolean
=======

   (Under construction.)

Synopsis
--------

     type
       Boolean = (False, True);
   or
     type
       Boolean (n)  { built-in type class }

Description
-----------

Conforming to
-------------

   `Boolean' is defined in ISO-7185 Standard Pascal and supported by
all known Pascal variants.

   `Boolean (n)' is a GPC extension.

Example
-------

     program BooleanDemo;
     var
       a: Boolean;
     begin
       a := True;
       WriteLn (a)
     end.

See also
--------


File: gpc,  Node: Break,  Next: Byte,  Prev: Boolean,  Up: Reference

Break
=====

Synopsis
--------

     Break  { simple statement }

Description
-----------

   With `Break' you can exit the body of the current loop instantly.
It can only be used within a WHILE, REPEAT or a FOR statement.

Conforming to
-------------

   `Break' is a Borland Pascal extension.

Example
-------

     program BreakDemo;
     var
       Foo: Integer;
     begin
       while True do
         begin
           repeat
             WriteLn ('Enter a number less than 100:');
             ReadLn (Foo);
             if Foo < 100 then
               Break;             { Exits repeat loop }
             WriteLn (Foo, ' is not exactly less than 100! Try again...')
           until False;
           if Foo > 50 then
             Break;              { Exits while loop }
           WriteLn ('The number entered was not greater then 50.')
         end
     end.

See also
--------

   *Note Loop Control Statements::, *Note Continue::, *Note Exit::,
*Note Halt::, *Note Return::, *Note goto::.


File: gpc,  Node: Byte,  Next: ByteBool,  Prev: Break,  Up: Reference

Byte
====

Synopsis
--------

     type
       Byte  { built-in type }

Description
-----------

   `Byte' is an unsigned integer type which is one "unit" wide.  On
most platforms one unit has 8 bits, therefore the type is named "byte"
and usually has a range of `0..255'. (It is the same as *Note
ByteCard::.)

   `Byte' in GNU Pascal is compatible to `unsigned char' in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `Byte' is a Borland Pascal extension. (For something equivalent in
ISO Pascal, see *Note Subrange Types::.)

Example
-------

     program ByteDemo;
     var
       a: Byte;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: ByteBool,  Next: ByteCard,  Prev: Byte,  Up: Reference

ByteBool
========

   (Under construction.)

Synopsis
--------

     type
       ByteBool = Boolean (BitSizeOf (Byte));

Description
-----------

Conforming to
-------------

Example
-------

     program ByteBoolDemo;
     var
       a: ByteBool;
     begin
       Byte (a) := 1;
       if a then WriteLn ('Ord (True) = 1')
     end.

See also
--------


File: gpc,  Node: ByteCard,  Next: ByteInt,  Prev: ByteBool,  Up: Reference

ByteCard
========

Synopsis
--------

     type
       ByteCard = Cardinal (BitSizeOf (Byte));

Description
-----------

   `ByteCard' is an unsigned integer type which is one "unit" wide.  On
most platforms one unit has 8 bits, therefore the type is prefixed
"byte-" and usually has a range of `0..255'.

   `ByteCard' in GNU Pascal is compatible to `unsigned char' in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `ByteCard' is a GNU Pascal extension.

Example
-------

     program ByteCardDemo;
     var
       a: ByteCard;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: ByteInt,  Next: C,  Prev: ByteCard,  Up: Reference

ByteInt
=======

Synopsis
--------

     type
       ByteInt = Integer (BitSizeOf (Byte));

Description
-----------

   `ByteInt' is a signed integer type which is one "unit" wide.  On
most platforms one unit has 8 bits, therefore the type is prefixed
"byte-" and usually has a range of `-128..127'.

   `ByteInt' in GNU Pascal is compatible to `signed char' in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `ByteInt' is a GNU Pascal extension.

   `ByteInt' in GNU Pascal corresponds to *Note ShortInt:: in Borland
Pascal.

Example
-------

     program ByteIntDemo;
     var
       a: ByteInt;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: C,  Next: Card,  Prev: ByteInt,  Up: Reference

C
=

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------

   *Note Importing Libraries from Other Languages::, *Note C_Language::


File: gpc,  Node: Card,  Next: Cardinal,  Prev: C,  Up: Reference

Card
====

Synopsis
--------

     function Card (S: ANY SET): Integer;

Description
-----------

   The function `Card (S)' returns the number of elements in the set
`S'.

Conforming to
-------------

   `Card' is an ISO 10206 Extended Pascal extension.

Example
-------

     program CardDemo;
     var
       Foo: set of 1 .. 100;
     begin
       Foo := [1, 2, 3, 5, 1, 1, 1, 2, 2, 2, 3, 3, 5, 5];  { four elements }
       WriteLn ('foo consists of ', Card (Foo), ' elements')
     end.

See also
--------

   *Note set::


File: gpc,  Node: Cardinal,  Next: case,  Prev: Card,  Up: Reference

Cardinal
========

Synopsis
--------

     type
       Cardinal  { built-in type }
   or
     type
       Cardinal (n)  { built-in type class }

Description
-----------

   `Cardinal' is the "natural" unsigned integer type in GNU Pascal.  On
most platforms it is 32 bits wide and thus has a range of
`0..4294967295'. Use it whenever you need a general-purpose unsigned
integer type and don't need to care about compatibility to other Pascal
dialects.

   As an extension, GPC allows to use `Cardinal' as a pseudo-schema to
produce types with a specified size in bits; for example

     type
       Card16 = Cardinal (16);

defines an unsigned integer type with 16 bits. The same mechanism works
for `Integer' and `Word', too.

   `Cardinal' in GNU Pascal is compatible to `unsigned int' in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `Cardinal' is not defined in ISO Pascal, but several Pascal
compilers support it as an extension. In Borland Delphi, for instance,
it is an unsigned 16-bit in version 1.0, an unsigned 31-bit integer
from version 2.0 on, and an unsigned 32-bit integer from version 4.0 on.

Example
-------

     program CardinalDemo;
     var
       a: Cardinal;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: case,  Next: Char,  Prev: Cardinal,  Up: Reference

case
====

Synopsis
--------

     case EXPRESSION of
       SELECTOR: STATEMENT;
       ...
       SELECTOR: STATEMENT;
     end;
   or, with alternative statement sequence:
     case EXPRESSION of
       SELECTOR: STATEMENT;
       ...
       SELECTOR: STATEMENT;
     otherwise                   { ``else'' instead of ``otherwise'' is allowed }
       STATEMENT;
       ...
       STATEMENT;
     end;
   or, as part of the invariant `record' type definition:
     foo = record
       FIELD DECLARATIONS
     case bar: VARIANT TYPE of
       SELECTOR: (FIELD DECLARATIONS);
       SELECTOR: (FIELD DECLARATIONS);
       ...
     end;
   or, without a variant selector field,
     foo = record
       FIELD DECLARATIONS
     case VARIANT TYPE of
       SELECTOR: (FIELD DECLARATIONS);
       SELECTOR: (FIELD DECLARATIONS);
       ...
     end;

Description
-----------

   `case' opens a case statement. For further description see *Note
case Statement::.

   For `case' in a variant record type definition, see *Note Record
Types::.

Conforming to
-------------

   The `case' statement is defined in ISO-7185 Standard Pascal and
supported by all known Pascal variants.

   According to ISO 7185 Pascal, the selector type must be a named type.
GNU Pascal, UCSD and Borland Pascal also allow a subrange here.

   The alternative statement execution with `otherwise' it is an
Extended Pascal extension; with `else' it is a Borland Pascal
extension. In GNU Pascal, both are allowed.

Example
-------

     program CaseDemo;
     var
       Foo: String (10);
       Bar: Integer;
     begin
       WriteLn ('Enter up to ten arbitrary characters:');
       ReadLn (Foo);
       for Bar := 1 to Length (Foo) do
         begin
           Write (Foo [bar], ' is ');
           case Foo [bar] of
             'A' .. 'Z', 'a' .. 'z':
               WriteLn ('an English letter');
             '0' .. '9':
               WriteLn ('a number');
           otherwise
             WriteLn ('an unrecognized character')
           end
         end
     end.

See also
--------

   *Note if Statement::, *Note Record Types::


File: gpc,  Node: Char,  Next: ChDir,  Prev: case,  Up: Reference

Char
====

   (Under construction.)

Synopsis
--------

     type
       Char  { built-in type }

Description
-----------

Conforming to
-------------

   `Char' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

     program CharDemo;
     var
       a: Char;
     begin
       a := 'x';
       WriteLn (a)
     end.

See also
--------


File: gpc,  Node: ChDir,  Next: Chr,  Prev: Char,  Up: Reference

ChDir
=====

Synopsis
--------

     procedure ChDir (Directory: String);

Description
-----------

   `ChDir' changes the current directory to DIRECTORY, if its argument
is a valid parameter to the related operating system's function.
Otherwise, a runtime error is caused.

Conforming to
-------------

   `ChDir' is a Borland Pascal extension.

Example
-------

     program ChDirDemo;
     var
       Foo: String (127);
     begin
       WriteLn ('Enter directory name to change to:');
       ReadLn (Foo);
       {$I-}  { Don't abort the program on error }
       ChDir (Foo);
       if IOResult <> 0 then
         WriteLn ('Cannot change to directory `', foo, '''.')
       else
         WriteLn ('Okay.')
     end.

See also
--------

   *Note MkDir::, *Note RmDir::


File: gpc,  Node: Chr,  Next: C_Language,  Prev: ChDir,  Up: Reference

Chr
===

Synopsis
--------

     function Chr (AsciiCode: Integer): Char;

Description
-----------

   `Chr' returns a character whose ASCII code corresponds to the value
given by `AsciiCode'.

Conforming to
-------------

   `Chr' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

     program ChrDemo;
     var
       x: Integer;
     begin
       for x := 32 to 122 do
         Write (Chr (x))
     end.

See also
--------

   *Note Ord::


File: gpc,  Node: C_Language,  Next: class,  Prev: Chr,  Up: Reference

C_Language
==========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------

   *Note Importing Libraries from Other Languages::, *Note C::


File: gpc,  Node: class,  Next: Close,  Prev: C_Language,  Up: Reference

class
=====

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Close,  Next: Cmplx,  Prev: class,  Up: Reference

Close
=====

   (Under construction.)

Synopsis
--------

     procedure Close (var F: ANY FILE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Cmplx,  Next: Comp,  Prev: Close,  Up: Reference

Cmplx
=====

Synopsis
--------

     function Cmplx (RealPart, ImaginaryPart: Real): Complex;

Description
-----------

   `Cmplx' makes a complex number from `RealPart' and `ImaginaryPart'.

Conforming to
-------------

   `Cmplx' is an ISO-10206 Extended Pascal extension.

Example
-------

     program CmplxDemo;
     var
       z: Complex;
       x, y: Real;
     begin
       z := Cmplx (x, y)  { z := x + iy }
     end.

See also
--------

   *Note Re::, *Note Im::, *Note Polar::, *Note Arg::


File: gpc,  Node: Comp,  Next: Complex,  Prev: Cmplx,  Up: Reference

Comp
====

Synopsis
--------

     type
       Comp = LongInt;

Description
-----------

   `Comp' is a signed integer type which is longer than `Integer'.  On
most platforms it is 64 bits wide and thus has a range of
`-9223372036854775808..9223372036854775807'.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `Comp' is a Borland Pascal extension.

   In some contexts, Borland Pascal treats `Comp' as a "real" type -
this behaviour is not supported by GPC.

Example
-------

     program CompDemo;
     var
       a: Comp;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: Complex,  Next: Concat,  Prev: Comp,  Up: Reference

Complex
=======

   (Under construction.)

Synopsis
--------

     type
       Internal_Complex = record { not visible }
         RealPart, ImaginaryPart: Real
       end;
       Complex = restricted Internal_Complex;

Description
-----------

Conforming to
-------------

   `Complex' is an ISO-10206 Extended Pascal extension.

Example
-------

     program ComplexDemo;
     var
       a: Complex;
     begin
       a := Cmplx (42, 3);
       WriteLn (Re (a), ' + ', Im (a), ' i')
     end.

See also
--------


File: gpc,  Node: Concat,  Next: Conjugate,  Prev: Complex,  Up: Reference

Concat
======

   (Under construction.)

Synopsis
--------

     function Concat (S1, S2: String): String;
   or
     function Concat (S1, S2, S3: String): String;
   or
     ...

Description
-----------

Conforming to
-------------

   `Concat' is a UCSD Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Conjugate,  Next: const,  Prev: Concat,  Up: Reference

Conjugate
=========

Synopsis
--------

     function Conjugate (z: Complex): Complex;

Description
-----------

   `Conjugate' computes the complex conjugate of the complex number `z'

Conforming to
-------------

   `Conjugate' is an ISO-10206 Extended Pascal extension.

Example
-------

     program ConjugateDemo;
     var
       z: Complex;
     begin
       z := Cmplx (2, 3);  { z is 2 + i * 3 }
       WriteLn ('z = ', Re (z) : 0 : 5, ' + i * ', Im (z) : 0 : 5);
       z := Conjugate (z);  { z conjugate is 2 - i * 3 }
       WriteLn ('z conjugate = ', Re (z) : 0 : 5,' + i * ', Im (z) : 0 : 5)
     end.

See also
--------

   *Note Cmplx::, *Note Re::, *Note Im::, *Note Abs::


File: gpc,  Node: const,  Next: constructor,  Prev: Conjugate,  Up: Reference

const
=====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

   `const' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

See also
--------


File: gpc,  Node: constructor,  Next: Continue,  Prev: const,  Up: Reference

constructor
===========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

   `constructor' is a Borland Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Continue,  Next: Copy,  Prev: constructor,  Up: Reference

Continue
========

Synopsis
--------

     Continue  { simple statement }

Description
-----------

   `Continue' goes on with loop iteration by jumping to the end of the
current loop body. Note: `Continue' can only stand within a WHILE,
REPEAT or a FOR statement.

Conforming to
-------------

   `Continue' is a Borland Pascal extension.

Example
-------

     program ContinueDemo;
     var
       Foo, Bar: Integer;
     begin
       WriteLn ('Enter three numbers:');
       for Bar := 1 to 3 do
         begin
           ReadLn (Foo);
           if Foo < 5 then
             Continue;
           WriteLn ('Your number was greater then 5.')
         end
     end.

See also
--------

   *Note Loop Control Statements::, *Note Break::, *Note Exit::, *Note
Halt::, *Note Return::, *Note goto::.


File: gpc,  Node: Copy,  Next: Cos,  Prev: Continue,  Up: Reference

Copy
====

Synopsis
--------

     function Copy (S: String; FirstChar, Count: Integer): String;
   or
     function Copy (S: String; FirstChar: Integer): String;

Description
-----------

   `Copy' returns a sub-string of `S' starting with the character at
position FIRSTCHAR. If COUNT is given, such many characters will be
copied into the sub-string. If COUNT is omitted, the sub-string will
will range to the end of S.

   If `Count' is too large for the sub-string to fit in S, the result
will be truncated at the end of S. If `FirstChar' exceeds the length of
S, the empty string will be returned. (For a function which does not
truncate but triggers a runtime error instead, see *Note SubStr::.)

   Please note that GPC's strings may be longer than 255 characters. If
you want to isolate the second half of a string S starting with the
third character, use `Copy (S, 3)' instead of `Copy (S, 3, 255)'.

Conforming to
-------------

   `Copy' is a UCSD Pascal extension. The possibility to omit the third
parameter is a GNU Pascal extension.

Example
-------

     program CopyDemo;
     var
       S: String (42);
     begin
       S := 'Hello';
       WriteLn (Copy (S, 2, 3));  { yields "ell" }
       WriteLn (Copy (S, 3));     { yields "llo" }
       WriteLn (Copy (S, 4, 7));  { yields "lo" }
       WriteLn (Copy (S, 42))     { yields the empty string }
     end.

See also
--------

   *Note SubStr::, String slice access.


File: gpc,  Node: Cos,  Next: CString,  Prev: Copy,  Up: Reference

Cos
===

Synopsis
--------

     function Cos (x: Real): Real;
   or
     function Cos (z: Complex): Complex;

Description
-----------

   `Cos' returns the cosine of the argument.  The result is in the
range `-1 < Cos (x) < 1' for real arguments.

Conforming to
-------------

   The function `Cos' is defined in ISO-7185 Standard Pascal; its
application to complex values is defined in ISO-10206 Extended Pascal.

Example
-------

     program CosDemo;
     begin
       WriteLn (Cos (SqRt (2) / 2) : 0 : 5)
         { yields 0.5 since Cos (SqRt (2) / 2) = 0.5 }
     end.

See also
--------

   *Note ArcTan::, *Note Sin::, *Note Ln::, *Note Arg::.


File: gpc,  Node: CString,  Next: CString2String,  Prev: Cos,  Up: Reference

CString
=======

   (Under construction.)

Synopsis
--------

     type
       CString = ^Char;

Description
-----------

Conforming to
-------------

Example
-------

     program CStringDemo;
     var
       s: CString;
     begin
       s := 'Hello, world!';
       {$X+}
       WriteLn (s)
     end.

See also
--------


File: gpc,  Node: CString2String,  Next: CStringCopyString,  Prev: CString,  Up: Reference

CString2String
==============

   (Under construction.)

Synopsis
--------

     function CString2String (S: CString): String;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: CStringCopyString,  Next: Date,  Prev: CString2String,  Up: Reference

CStringCopyString
=================

   (Under construction.)

Synopsis
--------

     function CStringCopyString (Dest: CString; const Source: String): CString;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Date,  Next: Dec,  Prev: CStringCopyString,  Up: Reference

Date
====

   (Under construction.)

Synopsis
--------

     function Date (T: TimeStamp): packed array [1 .. DATE LENGTH] of Char;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Dec,  Next: DefineSize,  Prev: Date,  Up: Reference

Dec
===

Synopsis
--------

   For ordinal types:
     procedure Dec (var x: ORDINAL TYPE);
   or
     procedure Dec (var x: ORDINAL TYPE; Amount: Integer);

   For pointer types:
     procedure Dec (var p: ANY POINTER TYPE);
   or
     procedure Dec (var p: ANY POINTER TYPE; Amount: Integer);

Description
-----------

   For ordinal types, `Dec' decreases the value of `x' by one or by
`amount' if specified.

   If the argument `p' is pointing to a specified type (typed pointer),
`Dec' decreases the address of `p' by the size of the type `p' is
pointing to or by `amount' times that size respectively. If `p' is an
untyped pointer (i.e. `p' is of type *Note Pointer::), `p' is decreased
by one, otherwise by `amount' if specified.

Conforming to
-------------

   `Dec' is a Borland Pascal extension. The combination of the second
argument with application to pointers is a GNU extension.

Example
-------

     program DecDemo;
     var
       x: Integer;
       y: array [1 .. 5] of Integer;
       p: ^Integer;
     begin
       x := 9;
       Dec (x, 10);     { yields -1 }
       {$X+}            { Turn on extended systax }
       p := @y [5];     { p points to y [5] }
       Dec (p, 3)       { p points to y [2] }
     end.

See also
--------

   *Note Inc::, *Note Pred::, *Note Succ::, *Note Pointer Arithmetics::.


File: gpc,  Node: DefineSize,  Next: Delete,  Prev: Dec,  Up: Reference

DefineSize
==========

   (Under construction.)

Synopsis
--------

     procedure DefineSize (var F: ANY FILE; NewSize: Integer);

Description
-----------

Conforming to
-------------

   `DefineSize' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Delete,  Next: destructor,  Prev: DefineSize,  Up: Reference

Delete
======

   (Under construction.)

Synopsis
--------

     procedure Delete (var S: String; FirstChar, Count: Integer);

Description
-----------

Conforming to
-------------

   `Delete' is a UCSD Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: destructor,  Next: Dispose,  Prev: Delete,  Up: Reference

destructor
==========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

   `destructor' is a Borland Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Dispose,  Next: div,  Prev: destructor,  Up: Reference

Dispose
=======

   (Under construction.)

Synopsis
--------

     Dispose (PointerVar: Pointer);
   or
     Dispose (PointerVar: Pointer; TAG FIELD VALUES);
   or
     Dispose (ObjectPointerVar: Pointer; DESTRUCTOR CALL);

Description
-----------

Conforming to
-------------

   `Dispose' is defined in ISO-7185 Standard Pascal and supported by
most known Pascal variants, but not by UCSD Pascal.  Its use for
objects is a Borland Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: div,  Next: do,  Prev: Dispose,  Up: Reference

div
===

   (Under construction.)

Synopsis
--------

     operator div (p, q: Integer) = r: Integer;

Description
-----------

Conforming to
-------------

   `div' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

See also
--------


File: gpc,  Node: do,  Next: Double,  Prev: div,  Up: Reference

do
==

Synopsis
--------

     for ... do
       STATEMENT
   or
     while ... do
       STATEMENT
   or
     with ... do
       STATEMENT
   or
     to begin do
       STATEMENT
   or
     to end do
       STATEMENT

Description
-----------

   The `do' reserved word is used in combination with other Pascal
keywords in many ways. For description and examples see the relevant
reference sections: `for', `while', `with', `to begin', `to end'.

Conforming to
-------------

   `do' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

   See references.

See also
--------

   *Note for::, *Note while::, *Note with::, *Note to begin do::, *Note
to end do::.


File: gpc,  Node: Double,  Next: downto,  Prev: do,  Up: Reference

Double
======

   (Under construction.)

Synopsis
--------

     type
       Double = Real;

Description
-----------

   `Double' is a synonym for the `Real' data type and supported for
compatibility with other compilers.

Conforming to
-------------

   `Double' is a Borland Pascal extension.

Example
-------

     program DoubleDemo;
     var
       A: Double;  { There is nothing special with `Double'. }
       B: Real;
     begin
       A := Pi;
       A := B
     end.

See also
--------


File: gpc,  Node: downto,  Next: else,  Prev: Double,  Up: Reference

downto
======

Synopsis
--------

     for VARIABLE := VALUE1 downto VALUE2 do
       STATEMENT

Description
-----------

   The `downto' reserved word is used in combination with `for' to
build a `for' loop.

Conforming to
-------------

   `downto' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

   See *Note for::.

See also
--------

   *Note for::.


File: gpc,  Node: else,  Next: Empty,  Prev: downto,  Up: Reference

else
====

Synopsis
--------

   As part of the `if' ... `then' ... `else' statement:
     if BOOLEAN EXPRESSION then
       STATEMENT1
     else
       STATEMENT2
   or, as part of the `case' ... `else' statement:
     case EXPRESSION of
       SELECTOR: STATEMENT;
       ...
       SELECTOR: STATEMENT
     else
       STATEMENT;
       ...
       STATEMENT
     end

Description
-----------

   `else' is part of the `if ... then ... else' statement which
provides a possibility to execute statements alternatively.  In the
`case' statement, `else' starts a series of statements which is
executed if no selector fit in EXPRESSION. In this case, `else' is a
synonym for `otherwise'.

Conforming to
-------------

   `else' in `if' statements is defined in ISO-7185 Standard Pascal and
supported by all known Pascal variants. `else' in `case' statements is
a Borland Pascal extension; ISO-10206 Extended Pascal has `otherwise'
instead.

Example
-------

     program ElseDemo;
     var
       i: Integer;
     begin
       Write ('Enter a number: ');
       ReadLn (i);
       if i > 42 then
         WriteLn ('The number is greater than 42')
       else
         WriteLn ('The number is not greater than 42')
     end.

See also
--------

   *Note if::, *Note case::, *Note otherwise::.


File: gpc,  Node: Empty,  Next: end,  Prev: else,  Up: Reference

Empty
=====

   (Under construction.)

Synopsis
--------

     function Empty (var F: ANY FILE): Boolean;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: end,  Next: EOF,  Prev: Empty,  Up: Reference

end
===

Synopsis
--------

     begin
       STATEMENT;
       STATEMENT;
       ...
       STATEMENT
     end

Description
-----------

   The reserved word `end' closes a `begin' ... `end'; statement which
joins several STATEMENTS together into one compound statement.

   @@ end of a <case> statement @@ end of a record or object declaration
@@ part of a <to end do> module destructor

Conforming to
-------------

   `end' is defined in ISO-7185 Standard Pascal and supported by all
Pascal variants.

Example
-------

     program EndDemo;
     begin
       if True then
         WriteLn ('single statement');
       if True then
         begin                     { clamp statement1 ... }
           WriteLn ('statement1');
           WriteLn ('statement2')
         end                       { ... to statement2 }
     end.

See also
--------

   *Note begin end Compound Statement::, *Note begin::


File: gpc,  Node: EOF,  Next: EOLn,  Prev: end,  Up: Reference

EOF
===

   (Under construction.)

Synopsis
--------

     function EOF (var F: ANY FILE): Boolean;
   or
     function EOF: Boolean;

Description
-----------

Conforming to
-------------

   `EOF' is defined in ISO-7185 Standard Pascal and supported by all
Pascal variants.

Example
-------

See also
--------


File: gpc,  Node: EOLn,  Next: EpsReal,  Prev: EOF,  Up: Reference

EOLn
====

   (Under construction.)

Synopsis
--------

     function EOLn (var F: ANY FILE): Boolean;
   or
     function EOLn: Boolean;

Description
-----------

Conforming to
-------------

   `EOLn' is defined in ISO-7185 Standard Pascal and supported by all
Pascal variants.

Example
-------

See also
--------


File: gpc,  Node: EpsReal,  Next: Eq,  Prev: EOLn,  Up: Reference

EpsReal
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

   `EpsReal' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Eq,  Next: Erase,  Prev: EpsReal,  Up: Reference

Eq
==

   (Under construction.)

Synopsis
--------

     function Eq (S1, S2: String): Boolean;

Description
-----------

Conforming to
-------------

   `Eq' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Erase,  Next: Exclude,  Prev: Eq,  Up: Reference

Erase
=====

   (Under construction.)

Synopsis
--------

     procedure Erase (var F: ANY FILE);

Description
-----------

Conforming to
-------------

   `Erase' is a Borland Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Exclude,  Next: Exit,  Prev: Erase,  Up: Reference

Exclude
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Exit,  Next: Exp,  Prev: Exclude,  Up: Reference

Exit
====

Synopsis
--------

     procedure Exit;

Description
-----------

   `Exit' leaves the currently executed procedure or function.  Note:
If `Exit' is called within the main program, it will be terminated
instantly.

Conforming to
-------------

   `Exit' is a UCSD Pascal extension. GNU Pascal does not support all
uses of `Exit' but only those defined in Borland Pascal.

Example
-------

     program ExitDemo;
     
     procedure Foo (Bar: Integer);
     var
       Baz, Fac: Integer;
     begin
       if Bar < 1 then
         Exit;                  { Exit foo }
       Fac := 1;
       for Baz := 1 to Bar do
         begin
           Fac := Fac * Baz;
           if Fac >= Bar then       { Exit foo }
             Exit;
           WriteLn (Bar,' is greater then ', baz, '!, which is equal to ', Fac)
       end
     end;
     
     begin
       Foo (-1);
       Foo (789);
       Exit;                  { Terminates program }
       Foo (987654321)        { This is not executed any more }
     end.

See also
--------

   *Note Break::, *Note Continue::, *Note Halt::


File: gpc,  Node: Exp,  Next: export,  Prev: Exit,  Up: Reference

Exp
===

Synopsis
--------

     function Exp (x: Real): Real;
   or
     function Exp (z: Complex): Complex;

Description
-----------

   The exponential function `Exp' computes the value of e to the power
of x, where the Euler number e = Exp (1) is the base of the natural
logarithm.

Conforming to
-------------

   The function `Exp' is defined in ISO-7185 Standard Pascal; its
application to complex values is defined in ISO-10206 Extended Pascal.

Example
-------

     program ExpDemo;
     var
       z: Complex;
     begin
       z := Cmplx (1, - 2 * Pi);  { z = 1 - i * 2 pi }
       z := Exp (z);  { yields e = Exp (1), since Exp ix = Cos (x) + i * Sin(x) }
       WriteLn (Ln (Re (z)) : 0 : 5)  { prints 1 = Ln (Exp (1)) }
     end.

See also
--------

   *Note Ln::


File: gpc,  Node: export,  Next: exports,  Prev: Exp,  Up: Reference

export
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

   `export' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: exports,  Next: Extend,  Prev: export,  Up: Reference

exports
=======

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

   `exports' is a Borland Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Extend,  Next: Extended,  Prev: exports,  Up: Reference

Extend
======

   (Under construction.)

Synopsis
--------

     procedure Extend (var F: ANY FILE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Extended,  Next: extern,  Prev: Extend,  Up: Reference

Extended
========

   (Under construction.)

Synopsis
--------

     type
       Extended = LongReal;

Description
-----------

Conforming to
-------------

Example
-------

     program ExtendedDemo;
     var
       a: Extended;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------


File: gpc,  Node: extern,  Next: external,  Prev: Extended,  Up: Reference

extern
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: external,  Next: Fail,  Prev: extern,  Up: Reference

external
========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Fail,  Next: False,  Prev: external,  Up: Reference

Fail
====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: False,  Next: far,  Prev: Fail,  Up: Reference

False
=====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: far,  Next: file,  Prev: False,  Up: Reference

far
===

Synopsis
--------

Description
-----------

   The `far' directive can be appended to a procedure or function
heading but is ignored by GPC. It is there for Borland compatibility,
only. (Since the GNU compilers provide a flat memory model, the
distinction between `near' and `far' pointers is void.)

Conforming to
-------------

   `far' is a Borland Pascal extension.

Example
-------

     program FarDemo;
     
     var
       p: procedure;
     
     {$W-}  { Don't warn about the uselessness of `far' }
     
     procedure Foo; far;  { `far' has no effect in GPC }
     begin
       WriteLn ('Foo')
     end;
     
     begin
       p := Foo;  { Would also work without `far' in GPC. }
       p
     end.

See also
--------

   *Note near::.


File: gpc,  Node: file,  Next: FileMode,  Prev: far,  Up: Reference

file
====

   (Under construction.)

Synopsis
--------

   In type definitions:
     File of TYPE
   or
     File

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: FileMode,  Next: FilePos,  Prev: file,  Up: Reference

FileMode
========

   (Under construction.)

Synopsis
--------

     var
       FileMode: Integer;

Description
-----------

Conforming to
-------------

   `FileMode' is a Borland Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: FilePos,  Next: FileSize,  Prev: FileMode,  Up: Reference

FilePos
=======

   (Under construction.)

Synopsis
--------

     function FilePos (var F: ANY FILE): Integer;

Description
-----------

Conforming to
-------------

   `FilePos' is a Borland Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: FileSize,  Next: FillChar,  Prev: FilePos,  Up: Reference

FileSize
========

   (Under construction.)

Synopsis
--------

     function FileSize (var F: ANY FILE): Integer;

Description
-----------

Conforming to
-------------

   `FileSize' is a Borland Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: FillChar,  Next: Flush,  Prev: FileSize,  Up: Reference

FillChar
========

   (Under construction.)

Synopsis
--------

     procedure FillChar (var Dest; Count: Integer; Val: Char);
   or
     procedure FillChar (var Dest; Count: Integer; Val: Byte);

Description
-----------

Conforming to
-------------

   `FillChar' is a UCSD Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: Flush,  Next: for,  Prev: FillChar,  Up: Reference

Flush
=====

   (Under construction.)

Synopsis
--------

     procedure Flush (var F: ANY FILE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: for,  Next: forward,  Prev: Flush,  Up: Reference

for
===

Synopsis
--------

   For ordinal index variables:
     for ORDINAL VARIABLE := INITIAL VALUE to FINAL VALUE do
       STATEMENT
   or
     for ORDINAL VARIABLE := INITIAL VALUE downto FINAL VALUE do
       STATEMENT

   For sets:
     for SET ELEMENT TYPE VARIABLE in SOME SET do
       STATEMENT

   For pointer index variables:
     for POINTER VARIABLE := INITIAL ADDRESS to FINAL ADDRESS do
       STATEMENT
   or
     for POINTER VARIABLE := INITIAL ADDRESS downto FINAL ADDRESS do
       STATEMENT

   @@ Set member iteration

Description
-----------

   The FOR statement is a count loop. For further information see *Note
for Statement::.

Conforming to
-------------

   `for' is defined in ISO-7185 Standard Pascal and supported by all
Pascal variants. Iteration of Pointers is a Borland Pascal extension.
Set member iteration is an ISO-10206 Extended Pascal extension.

Example
-------

     program ForDemo;
     var
       CharSet: set of Char;
       c: Char;
       n: Integer;
       Fac: array [0 .. 10] of Integer;
       PInt: ^Integer;
     begin
        CharSet := ['g', 'p', 'c'];
        for c in CharSet do
          WriteLn (c);       { prints c g p in three lines }
        Fac [0] := 1;
        for n := 1 to 10 do  { computes the factorial of n for n = 0 .. 10 }
          Fac [n] := Fac [n - 1] * n;
        {$X+}
        { prints n! for n = 0 .. 10 }
        for PInt := @Fac [0] to @Fac [10] do
          WriteLn (PInt - @Fac [0], '! = ', PInt^)
     end.

See also
--------

   *Note Set Types::, *Note Pointer Arithmetics::


File: gpc,  Node: forward,  Next: Frac,  Prev: for,  Up: Reference

forward
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Frac,  Next: FrameAddress,  Prev: forward,  Up: Reference

Frac
====

   (Under construction.)

Synopsis
--------

     function Frac (x: Real): Real;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: FrameAddress,  Next: FreeMem,  Prev: Frac,  Up: Reference

FrameAddress
============

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: FreeMem,  Next: function,  Prev: FrameAddress,  Up: Reference

FreeMem
=======

Synopsis
--------

     procedure FreeMem (var p: Pointer; Size: Cardinal);
   or
     procedure FreeMem (var p: Pointer);

Description
-----------

   Releases a chunk of memory previously allocated using `GetMem'.  The
parameter SIZE is optional, and its value is ignored.

   Since Extended Pascal's schemata provide a cleaner way to implement
dynamical arrays and such, we recommend using `GetMem' and `FreeMem'
only for low-level applications or for interfacing with other languages.

Conforming to
-------------

   `FreeMem' is a Borland Pascal extension. `FreeMem' with only one
parameter is a GNU Pascal extension.

Example
-------

   *Note GetMem::.

See also
--------

   *Note GetMem::, *Note Schema Types::, *Note Dispose::, *Note Mark::,
*Note Release::.


File: gpc,  Node: function,  Next: GE,  Prev: FreeMem,  Up: Reference

function
========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: GE,  Next: Get,  Prev: function,  Up: Reference

GE
==

   (Under construction.)

Synopsis
--------

     function GE (S1, S2: String): Boolean;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Get,  Next: GetMem,  Prev: GE,  Up: Reference

Get
===

   (Under construction.)

Synopsis
--------

     procedure Get (var F: TYPED FILE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: GetMem,  Next: GetTimeStamp,  Prev: Get,  Up: Reference

GetMem
======

Synopsis
--------

     procedure GetMem (var p: Pointeger; Size: Cardinal);
   or
     function GetMem (Size: Cardinal): Pointer;

Description
-----------

   Allocates dynamical storage on the heap and returns a pointer to it
in `p' or as the function result.

   Since Extended Pascal's schemata provide a cleaner way to implement
dynamical arrays and such, we recommend using `GetMem' and `FreeMem'
only for low-level applications.

Conforming to
-------------

   `GetMem' is a Borland Pascal extension.  The use of `GetMem' as a
function is a GNU Pascal extension.

Example
-------

   The Borland-comatibility unit `Graph' from the `BPcompat' package
supports a `GetImage' and a `PutImage' procedure which need a variable
of size `ImageSize' as a buffer.  Since these are "black box" routines,
the buffer can't reasonably be a schema providing a dynamical array.
Instead, we have to use `GetMem' and `FreeMem' for dynamical memory
allocation.

     program GetMemDemo;
     var
       Buffer: Pointer;
       Size: Cardinal;
     begin
       Size := Random (10000); { the size can be determined at run time }
       Buffer := GetMem (Size);  { or: GetMem (Buffer, Size); }
       { Do something with Buffer }
       FreeMem (Buffer)  { or: FreeMem (Buffer, Size) }
     end.

See also
--------

   *Note FreeMem::, *Note New::, *Note Schema Types::.


File: gpc,  Node: GetTimeStamp,  Next: goto,  Prev: GetMem,  Up: Reference

GetTimeStamp
============

   (Under construction.)

Synopsis
--------

     procedure GetTimeStamp (var T: TimeStamp);

Description
-----------

Conforming to
-------------

   `GetTimeStamp' is an ISO-10206 Extended Pascal extension.

Example
-------

See also
--------


File: gpc,  Node: goto,  Next: GT,  Prev: GetTimeStamp,  Up: Reference

goto
====

   (Under construction.)

Synopsis
--------

     goto LABEL

Description
-----------

   The `goto' statement transfers control to statement with the label
`label'.

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: GT,  Next: Halt,  Prev: goto,  Up: Reference

GT
==

   (Under construction.)

Synopsis
--------

     function GT (S1, S2: String): Boolean;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Halt,  Next: High,  Prev: GT,  Up: Reference

Halt
====

Synopsis
--------

     Halt;
   or
     Halt (ExitCode: Integer);

Description
-----------

   `Halt' terminates the program with exitcode 0. If `ExitCode', is
specified, it is returned by `Halt' on exit.

Conforming to
-------------

   `Halt' is an UCSD Pascal extension.

Example
-------

     program HaltDemo;
     begin
       WriteLn ('This string will always be this program''s output.');
       Halt;  { Terminate right here and right now. }
       WriteLn ('And this string won''t ever!')
     end.

See also
--------

   *Note Break::, *Note Continue::, *Note Exit::, *Note Return::, *Note
goto::.


File: gpc,  Node: High,  Next: if,  Prev: Halt,  Up: Reference

High
====

Synopsis
--------

     function High (ORDINAL TYPE OR VARIABLE): ORDINAL TYPE;
   or
     function High (ARRAY TYPE OR VARIABLE): ARRAY INDEX TYPE;
   or
     function High (STRING VARIABLE): Integer;

Description
-----------

   For ordinal types or variables of that type, `High' returns the
highest value a variable of that type can assume.

   For array types or variables of that type, `High' returns the
highest index a variable of that type can assume. Note: the result is of
the same type as the array index is. If the array has more than one
dimension, `High' returns the highest index in the first dimension.

   If the argument is a string variable, `High' returns the
discriminant of the string type (i.e. its capacity).

Conforming to
-------------

   `High' is a Borland Pascal extension.

Example
-------

     program HighDemo;
     type
       Colors = (Red, Green, Blue);
     var
       Col: array [Colors] of (Love, Hope, Faithfulness);
       Foo: Colors;
       Bar: Integer;
       Baz: String (123);
     begin
       Foo := High (Col);              { yields Blue }
       Bar := Ord (High (Col [Foo]));  { yields Ord (Faithfulness), i.e., 2 }
       Bar := High (Integer);          { returns highest possible ``Integer'' }
       Bar := High (Baz)               { returns 123 }
     end.

See also
--------

   *Note Low::


File: gpc,  Node: if,  Next: Im,  Prev: High,  Up: Reference

if
==

Synopsis
--------

     if BOOLEAN EXPRESSION then
       STATEMENT
   or with an alternative statement:
     if BOOLEAN EXPRESSION then
       STATEMENT1
     else
       STATEMENT2

Description
-----------

   The `if ... then' statement executes STATEMENT1 depending on
`Boolean expression' being true. If `else' is specified, it continues
executing STATEMENT2 instead.

Conforming to
-------------

   `if' is defined in ISO-7185 Standard Pascal and supported by all
Pascal variants.

Example
-------

     program IfDemo;
     var
       Foo, Bar: Boolean;
     begin
       Foo := True;
       Bar := False;
       if ((1 = 1) or (2 = 3)) and (Foo = not Bar) then
         begin
           { This is executed if either Foo is true but not Bar or vice versa }
           WriteLn ('Either Foo or Bar is true.');
           if Bar then
             WriteLn ('You will see this text if Bar is true.')
         end
       else { This whole `else' branch is not executed }
         if 1 = 1 then
           if True = False then
             WriteLn ('This text is never written on screen.')
           else  { Note: This ``else'' belongs to ``if True = False'' }
             WriteLn ('This text is never written on screen as well.')
         else  { Note: This ``else'' belongs to ``if 1 = 1'' }
           WriteLn ('Nor is this.')
     end.

See also
--------

   *Note if Statement::, *Note else::, *Note then::


File: gpc,  Node: Im,  Next: implementation,  Prev: if,  Up: Reference

Im
==

Synopsis
--------

     function Im (z: Complex): Real;

Description
-----------

   `Im' extracts the imaginary part of the complex number `z'.  The
result is a real value.

Conforming to
-------------

   `Im' is an ISO-10206 Extended Pascal extension.

Example
-------

     program ImDemo;
     var
       z: Complex;
     begin
       z := Cmplx (1, 2);  { 1 + i * 2 }
       WriteLn (Im (z) : 0 : 5)  { 2.00000 }
     end.

See also
--------

   *Note Cmplx::, *Note Re::, *Note Arg::.


File: gpc,  Node: implementation,  Next: import,  Prev: Im,  Up: Reference

implementation
==============

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: import,  Next: in,  Prev: implementation,  Up: Reference

import
======

Synopsis
--------

     program @@fragment foo;
     
     import
       bar1;
       bar3 (baz1 => glork1) in 'baz.pas';
       bar2 only (baz2, baz3 => glork2);
     
     [...]

Description
-----------

   The reserved word `import' in the _import part_ of a program makes
the program import an interface.

   The `in' above tells GPC to look for the module in the specified
file; otherwise the file name is derived from the name of the interface
by adding first `.p', then `.pas' - which only works if the name of the
exported interface coincides with the file name.

   The symbol `=>' denotes import renaming: The entity which is
exported under the name `baz1' by the interface `bar3' will be known
under the new name `glork1' in the program.

   The `only' qualifier means that only the listed identifiers will be
imported from the interface. Renaming works together with `only', too.

   There must be at most one import part in a program.

   The interfaces needn't be exported by Extended Pascal modules but
may be UCSD/Borland Pascal units as well.

Conforming to
-------------

   `import' and modules in general are an ISO-10206 Extended Pascal
extension.

   GNU Pascal does not yet support `qualified' import.

Example
-------

See also
--------

   *Note module::, *Note unit::, *Note uses::.


File: gpc,  Node: in,  Next: Inc,  Prev: import,  Up: Reference

in
==

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Inc,  Next: Include,  Prev: in,  Up: Reference

Inc
===

Synopsis
--------

   For ordinal types:
     procedure Inc (var x: ORDINAL TYPE);
   or
     procedure Inc (var x: ORDINAL TYPE; Amount: Integer);

   For pointer types:
     procedure Inc (var p: ANY POINTER TYPE);
   or
     procedure Inc (var p: ANY POINTER TYPE; Amount: Integer);

Description
-----------

   For ordinal types, `inc' increases the value of `x' by one or by
`amount' if it is given.

   If the argument `p' is pointing to a specified type (typed pointer),
`inc' increases the address of `p' by the size of the type `p' is
pointing to or by `amount' times that size respectively. If `p' is an
untyped pointer (i.e. `p' is of type *Note Pointer::), `p' is increased
by one.

Conforming to
-------------

   `Inc' is a Borland Pascal extension.  Yet application of `Inc' to
pointers is defined in Borland Pascal.  The combination of the second
argument with application to pointers is a GNU extension.

Example
-------

     program IncDemo;
     var
       Foo: Integer;
       Bar: array [1 .. 5] of Integer;
       Baz: ^Integer;
     begin
       Foo := 4;
       Inc (Foo, 5);      { yields 9 }
       {$X+}              { Turn on extended systax }
       Baz := @Bar [1];  { Baz points to y [1] }
       Inc (Baz, 2);      { Baz points to y [3] }
     end.

See also
--------

   *Note Dec::, *Note Pred::, *Note Succ::, *Note Pointer Arithmetics::.


File: gpc,  Node: Include,  Next: Index,  Prev: Inc,  Up: Reference

Include
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Index,  Next: inherited,  Prev: Include,  Up: Reference

Index
=====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: inherited,  Next: inline,  Prev: Index,  Up: Reference

inherited
=========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: inline,  Next: InOutRes,  Prev: inherited,  Up: Reference

inline
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: InOutRes,  Next: InOutResStr,  Prev: inline,  Up: Reference

InOutRes
========

   (Under construction.)

Synopsis
--------

     var
       InOutRes: Integer;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: InOutResStr,  Next: Input,  Prev: InOutRes,  Up: Reference

InOutResStr
===========

   (Under construction.)

Synopsis
--------

     var
       InOutResStr: CString;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Input,  Next: Insert,  Prev: InOutResStr,  Up: Reference

Input
=====

   (Under construction.)

Synopsis
--------

     var
       Input: Text;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Insert,  Next: Int,  Prev: Input,  Up: Reference

Insert
======

   (Under construction.)

Synopsis
--------

     procedure Insert (Source: String; var Dest: String; Position: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Int,  Next: Integer,  Prev: Insert,  Up: Reference

Int
===

   (Under construction.)

Synopsis
--------

     function Int (x: Real): Real;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Integer,  Next: interface,  Prev: Int,  Up: Reference

Integer
=======

Synopsis
--------

     type
       Integer  { built-in type }
   or
     type
       Integer (n)  { built-in type class }

Description
-----------

   `Integer' is the "natural" signed integer type in GNU Pascal.  On
most platforms it is 32 bits wide and thus has a range of
`-2147483648..2147483647'.  Use it whenever you need a general-purpose
signed integer type.

   As an extension, GPC allows to use `Integer' as a pseudo-schema to
produce types with a specified size in bits; for example

     type
       Int16 = Integer (16);

   defines an integer type with 16 bits.  The same mechanism works for
`Cardinal' and `Word', too.

   `Integer' in GNU Pascal is compatible to `Int' in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   In ISO Pascal, `Integer' is the only built-in integer type.
(However see *Note Subrange Types::.)

Example
-------

     program IntegerDemo;
     var
       a: Integer;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: interface,  Next: interrupt,  Prev: Integer,  Up: Reference

interface
=========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: interrupt,  Next: IOResult,  Prev: interface,  Up: Reference

interrupt
=========

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: IOResult,  Next: is,  Prev: interrupt,  Up: Reference

IOResult
========

   (Under construction.)

Synopsis
--------

     function IOResult: Integer;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: is,  Next: label,  Prev: IOResult,  Up: Reference

is
==

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: label,  Next: LastPosition,  Prev: is,  Up: Reference

label
=====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: LastPosition,  Next: LE,  Prev: label,  Up: Reference

LastPosition
============

   (Under construction.)

Synopsis
--------

     function LastPosition (var F: TYPED FILE): Integer;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: LE,  Next: Length,  Prev: LastPosition,  Up: Reference

LE
==

   (Under construction.)

Synopsis
--------

     function LE (S1, S2: String): Boolean;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Length,  Next: library,  Prev: LE,  Up: Reference

Length
======

   (Under construction.)

Synopsis
--------

     function Length (S: String): Integer;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: library,  Next: Ln,  Prev: Length,  Up: Reference

library
=======

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Ln,  Next: LoCase,  Prev: library,  Up: Reference

Ln
==

Synopsis
--------

     function Ln (x: Real): Real;
   or
     function Ln (z: Complex): Complex;

Description
-----------

   The natural logarith `Ln' is the logarithm with base e, where e is
the Euler number e = Exp (1) = 2.718281828...

Conforming to
-------------

   The function `Ln' is defined in ISO-7185 Standard Pascal; its
application to complex values is defined in ISO-10206 Extended Pascal.

Example
-------

     program LnDemo;
     var
       z: Complex;
     begin
       z := Cmplx (1, 1);
       z := Ln (z)  { yields Ln (SqRt (2)) + i * Pi / 4 }
                    { since Ln (i * x) = Ln Abs (x) + i * Arg (x) }
     end.

See also
--------


File: gpc,  Node: LoCase,  Next: LongBool,  Prev: Ln,  Up: Reference

LoCase
======

   (Under construction.)

Synopsis
--------

     function LoCase (Ch: Char): Char;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: LongBool,  Next: LongCard,  Prev: LoCase,  Up: Reference

LongBool
========

   (Under construction.)

Synopsis
--------

     type
       LongBool = Boolean (BitSizeOf (LongInt));

Description
-----------

Conforming to
-------------

Example
-------

     program LongBoolDemo;
     var
       a: LongBool;
     begin
       LongInt (a) := 1;
       if a then WriteLn ('Ord (True) = 1')
     end.

See also
--------


File: gpc,  Node: LongCard,  Next: LongestBool,  Prev: LongBool,  Up: Reference

LongCard
========

Synopsis
--------

     type
       LongCard = Cardinal (BitSizeOf (LongInt));

Description
-----------

   `LongCard' is an unsigned integer type which is longer than
`Cardinal'.  On most platforms it is 64 bits wide and thus has a range
of `0..18446744073709551615'.

   `LongCard' in GNU Pascal is compatible to `long long unsigned int'
in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `LongCard' is a GNU Pascal extension.

Example
-------

     program LongCardDemo;
     var
       a: LongCard;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: LongestBool,  Next: LongestCard,  Prev: LongCard,  Up: Reference

LongestBool
===========

   (Under construction.)

Synopsis
--------

     type
       LongestBool = Boolean (BitSizeOf (LongestInt));

Description
-----------

Conforming to
-------------

Example
-------

     program LongestBoolDemo;
     var
       a: LongestBool;
     begin
       LongestInt (a) := 1;
       if a then WriteLn ('Ord (True) = 1')
     end.

See also
--------


File: gpc,  Node: LongestCard,  Next: LongestInt,  Prev: LongestBool,  Up: Reference

LongestCard
===========

Synopsis
--------

     type
       LongestCard = Cardinal (BitSizeOf (LongestInt));

Description
-----------

   `LongestCard' is GPC's longest-possible unsigned integer type.
Currently, this is the same as *Note LongCard::.  On most platforms it
is 64 bits wide and thus has a range of `0..18446744073709551615'.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `LongestCard' is a GNU Pascal extension.

Example
-------

     program LongestCardDemo;
     var
       a: LongestCard;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: LongestInt,  Next: LongestReal,  Prev: LongestCard,  Up: Reference

LongestInt
==========

Synopsis
--------

     type
       LongestInt = LongInt;  { might get bigger than LongInt someday }

Description
-----------

   `LongestInt' is GPC's longest-possible signed integer type.
Currently, this is the same as *Note LongInt::.  On most platforms it
is 64 bits wide and thus has a range of
`-9223372036854775808..9223372036854775807'.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `LongestInt' is a GNU Pascal extension.

Example
-------

     program LongestIntDemo;
     var
       a: LongestInt;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: LongestReal,  Next: LongestWord,  Prev: LongestInt,  Up: Reference

LongestReal
===========

   (Under construction.)

Synopsis
--------

     type
       LongestReal = LongReal;  { might get bigger than LongReal someday }

Description
-----------

Conforming to
-------------

Example
-------

     program LongestRealDemo;
     var
       a: LongestReal;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------


File: gpc,  Node: LongestWord,  Next: LongInt,  Prev: LongestReal,  Up: Reference

LongestWord
===========

Synopsis
--------

     type
       LongestWord = LongestCard;

Description
-----------

   `LongestWord' is GPC's longest-possible unsigned integer type.
Currently, this is the same as *Note LongWord::.  On most platforms it
is 64 bits wide and thus has a range of `0..18446744073709551615'.  (It
is the same as *Note LongestCard::.)

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `LongestWord' is a GNU Pascal extension.

Example
-------

     program LongestWordDemo;
     var
       a: LongestWord;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: LongInt,  Next: LongReal,  Prev: LongestWord,  Up: Reference

LongInt
=======

Synopsis
--------

     type
       LongInt  { built-in type }

Description
-----------

   `LongInt' is a signed integer type which is longer than `Integer'.
On most platforms it is 64 bits wide and thus has a range of
`-9223372036854775808..9223372036854775807'.

   `LongInt' in GNU Pascal is compatible to `long long int' in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `LongInt' is a Borland Pascal extension.  Borland Pascal defines
`LongInt' as a 32-bit signed integer type (*Note Integer:: in GNU
Pascal).

Example
-------

     program LongIntDemo;
     var
       a: LongInt;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: LongReal,  Next: LongWord,  Prev: LongInt,  Up: Reference

LongReal
========

   (Under construction.)

Synopsis
--------

     type
       LongReal  { built-in type }

Description
-----------

Conforming to
-------------

Example
-------

     program LongRealDemo;
     var
       a: LongReal;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------


File: gpc,  Node: LongWord,  Next: Low,  Prev: LongReal,  Up: Reference

LongWord
========

Synopsis
--------

     type
       LongWord = LongCard;

Description
-----------

   `LongWord' is an unsigned integer type which is larger than `Word'.
On most platforms it is 64 bits wide and thus has a range of
`0..18446744073709551615'.  It is the same as *Note LongCard::.

   `LongWord' in GNU Pascal is compatible to `long long unsigned int'
in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `LongWord' is a GNU Pascal extension.

Example
-------

     program LongWordDemo;
     var
       a: LongWord;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: Low,  Next: LT,  Prev: LongWord,  Up: Reference

Low
===

Synopsis
--------

     function Low (ORDINAL TYPE OR VARIABLE): ORDINAL TYPE;
   or
     function Low (ARRAY TYPE OR VARIABLE): ARRAY ELEMENT TYPE;
   or
     function Low (STRING VARIABLE): Integer;

Description
-----------

   For ordinal types or variables of that type, `Low' returns the
lowest value a variable of that type can assume.

   For array types or variables of that type, `Low' returns the lowest
index a variable of that type can assume. Note: the result is of the
same type as the array index is. If the array has more than one
dimension, `Low' returns the lowest index in the first dimension.

   If the argument is a string variable, `Low' returns one.

Conforming to
-------------

Example
-------

     program LowDemo;
     type
       Colors = (Red, Green, Blue);
     var
       Col: array [12 .. 20] of Colors;
       Foo: 12 .. 20;
       Bar: Integer;
     begin
       Foo := Low (Col);              { returns 12 }
       Col [Foo] := Low (Col [Foo]);  { returns Red }
       Bar := Low (Integer)           { returns lowest ``Integer'' value }
     end.

See also
--------

   *Note High::


File: gpc,  Node: LT,  Next: Mark,  Prev: Low,  Up: Reference

LT
==

   (Under construction.)

Synopsis
--------

     function LT (S1, S2: String): Boolean;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Mark,  Next: Max,  Prev: LT,  Up: Reference

Mark
====

   (Under construction.)

Synopsis
--------

     procedure Mark (var P: Pointer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Max,  Next: MaxChar,  Prev: Mark,  Up: Reference

Max
===

   (Under construction.)

Synopsis
--------

     function Max (x1, x2: ORDINAL OR REAL TYPE): SAME TYPE;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: MaxChar,  Next: MaxInt,  Prev: Max,  Up: Reference

MaxChar
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: MaxInt,  Next: MaxReal,  Prev: MaxChar,  Up: Reference

MaxInt
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: MaxReal,  Next: MedBool,  Prev: MaxInt,  Up: Reference

MaxReal
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: MedBool,  Next: MedCard,  Prev: MaxReal,  Up: Reference

MedBool
=======

   (Under construction.)

Synopsis
--------

     type
       MedBool = Boolean (BitSizeOf (MedInt));

Description
-----------

Conforming to
-------------

Example
-------

     program MedBoolDemo;
     var
       a: MedBool;
     begin
       MedInt (a) := 1;
       if a then WriteLn ('Ord (True) = 1')
     end.

See also
--------


File: gpc,  Node: MedCard,  Next: MedInt,  Prev: MedBool,  Up: Reference

MedCard
=======

Synopsis
--------

     type
       MedCard = Cardinal (BitSizeOf (MedInt));

Description
-----------

   `MedCard' is an unsigned integer type which is not smaller than
`Cardinal'.  On most platforms it actually is the same as `Cardinal'
and 32 bits wide and thus has a range of `0..4294967295'.

   `MedCard' in GNU Pascal is compatible to `long unsigned int' in GNU
C.  This compatibility is the reason why `MedCard' exists.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `MedCard' is a GNU Pascal extension.

Example
-------

     program MedCardDemo;
     var
       a: MedCard;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: MedInt,  Next: MedReal,  Prev: MedCard,  Up: Reference

MedInt
======

Synopsis
--------

     type
       MedInt  { built-in type }

Description
-----------

   `MedInt' is a signed integer type which is not smaller than
`Integer'.  On most platforms it actually is the same as `Integer' and
32 bits wide and thus has a range of `-2147483648..2147483647'.

   `MedInt' in GNU Pascal is compatible to `long int' in GNU C.  This
compatibility is the reason why `MedInt' exists.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `MedInt' is a GNU Pascal extension.

Example
-------

     program MedIntDemo;
     var
       a: MedInt;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: MedReal,  Next: MedWord,  Prev: MedInt,  Up: Reference

MedReal
=======

   (Under construction.)

Synopsis
--------

     type
       MedReal = Real;

Description
-----------

Conforming to
-------------

Example
-------

     program MedRealDemo;
     var
       a: MedReal;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------


File: gpc,  Node: MedWord,  Next: Min,  Prev: MedReal,  Up: Reference

MedWord
=======

Synopsis
--------

     type
       MedWord = MedCard;

Description
-----------

   `MedWord' is an unsigned integer type which is not smaller than
`Word'.  On most platforms it actually is the same as `Word' and 32
bits wide and thus has a range of `0..4294967295'.  It is the same as
*Note MedCard::.

   `MedWord' in GNU Pascal is compatible to `long unsigned int' in GNU
C.  This compatibility is the reason why `MedWord' exists.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `MedWord' is a GNU Pascal extension.

Example
-------

     program MedWordDemo;
     var
       a: MedWord;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: Min,  Next: MinReal,  Prev: MedWord,  Up: Reference

Min
===

   (Under construction.)

Synopsis
--------

     function Min (x1, x2: ORDINAL OR REAL TYPE): SAME TYPE;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: MinReal,  Next: MkDir,  Prev: Min,  Up: Reference

MinReal
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: MkDir,  Next: mod,  Prev: MinReal,  Up: Reference

MkDir
=====

Synopsis
--------

     procedure MkDir (Directory: String);

Description
-----------

   `MkDir' creates the given DIRECTORY, if its argument is a valid
parameter to the related operating system's function.  Otherwise a
runtime error is caused.

Conforming to
-------------

   `MkDir' is a Borland Pascal extension.

Example
-------

     program MkDirDemo;
     var
       Foo: String (127);
     begin
       WriteLn ('Enter directory name to create:');
       ReadLn (Foo);
       {$I-}  { Don't abort program on error }
       MkDir (Foo);
       if IOResult <> 0 then
         WriteLn ('Directory `', Foo, ''' could not be created')
       else
         WriteLn ('Okay')
     end.

See also
--------

   *Note ChDir::, *Note RmDir::


File: gpc,  Node: mod,  Next: module,  Prev: MkDir,  Up: Reference

mod
===

   (Under construction.)

Synopsis
--------

     operator mod (p, q: Integer) = r: Integer;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: module,  Next: Move,  Prev: mod,  Up: Reference

module
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Move,  Next: MoveLeft,  Prev: module,  Up: Reference

Move
====

   (Under construction.)

Synopsis
--------

     procedure Move (const Source; var Dest; Count: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: MoveLeft,  Next: MoveRight,  Prev: Move,  Up: Reference

MoveLeft
========

   (Under construction.)

Synopsis
--------

     procedure MoveLeft (const Source; var Dest; Count: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: MoveRight,  Next: Name,  Prev: MoveLeft,  Up: Reference

MoveRight
=========

   (Under construction.)

Synopsis
--------

     procedure MoveRight (const Source; var Dest; count: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Name,  Next: NE,  Prev: MoveRight,  Up: Reference

Name
====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: NE,  Next: near,  Prev: Name,  Up: Reference

NE
==

   (Under construction.)

Synopsis
--------

     function NE (S1, S2: String): Boolean;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: near,  Next: New,  Prev: NE,  Up: Reference

near
====

Synopsis
--------

Description
-----------

   The `near' directive can be appended to a procedure or function
heading but is ignored by GPC. It is there for Borland compatibility,
only. (Since the GNU compilers provide a flat memory model, the
distinction between `near' and `near' pointers is void.)

Conforming to
-------------

   `near' is a Borland Pascal extension.

Example
-------

     program NearDemo;
     
     var
       p: procedure;
     
     {$W-}  { Don't warn about the uselessness of `near' }
     
     procedure Foo; near;  { `near' has no effect in GPC }
     begin
       WriteLn ('Foo')
     end;
     
     begin
       p := Foo;  { Works, despite the `near'. }
       p
     end.

See also
--------

   *Note far::.


File: gpc,  Node: New,  Next: NewCString,  Prev: near,  Up: Reference

New
===

   (Under construction.)

Synopsis
--------

     procedure New (var P: ANY POINTER);
   or
     procedure New (var P: POINTER TO A VARIANT RECORD; TAG FIELDS);
   or
     procedure New (var P: POINTER TO A SCHEMA; DISCRIMINANTS);
   or
     procedure New (var P: POINTER TO AN OBJECT; CONSTRUCTOR CALL);
   or
     function New (ANY POINTER TYPE): SAME TYPE;
   or
     function New (VARIANT RECORD POINTER TYPE;
                   TAG FIELDS): SAME TYPE;
   or
     function New (SCHEMA POINTER TYPE;
                   DISCRIMINANTS): SAME TYPE;
   or
     function New (OBJECT POINTER TYPE;
                   CONSTRUCTOR CALL): SAME TYPE;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: NewCString,  Next: nil,  Prev: New,  Up: Reference

NewCString
==========

   (Under construction.)

Synopsis
--------

     function NewCString (const S: String): CString;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: nil,  Next: not,  Prev: NewCString,  Up: Reference

nil
===

Synopsis
--------

   `nil' is a predefined constant

Description
-----------

   `nil' is a predefined pointer constant that indicates an unassigned
pointer. "nil" stands for "not in list". _Every_ pointer type can be
associated with this constant.

Conforming to
-------------

   `nil' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

     program NilDemo;
     const
       NodeNum = 10;
     type
       PNode = ^TNode;
       TNode = record
         Key: Integer;
         Next: PNode
       end;
     var
       Root, Node: PNode;
       Foo: Integer;
     begin
       New (Root);
       Root^.Key := 1;             { Set root key }
       Node := Root;
       for Foo := 2 to NodeNum do  { Create linked list with NODE_NUM nodes }
         begin
           New (Node^.Next);
           Node := Node^.Next;
           Node^.Key := Foo        { Set key }
         end;
       Node^.Next := nil;          { Mark end of linked list }
       { Shorten list by removing its first element until list is empty }
       while Root <> nil do
         begin
           Node := Root;
           WriteLn ('Current key:', Root^.Key);
           Root := Root^.Next;
           Dispose (Node);
           Node := nil             { Indicate old node is not assigned }
         end
     end.

See also
--------

   *Note Assigned::, *Note Pointer::


File: gpc,  Node: not,  Next: Null,  Prev: nil,  Up: Reference

not
===

   (Under construction.)

Synopsis
--------

     operator not (b1, b2: Boolean) = Result: Boolean;
   or
     operator not (i1, i2: INTEGER TYPE) = Result: INTEGER TYPE;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Null,  Next: object,  Prev: not,  Up: Reference

Null
====

Synopsis
--------

     var
       Null: Void absolute 0;

Description
-----------

   `Null' is a predefined variable at address `nil'.  `Null' can be
passed as a "void" argument to a procedure, function or operator
expecting a "var" parameter. _Note_: Make sure they can handle this
case, otherwise this is likely to cause an exception and the program
will be terminated. Since `Null' is an L-value, it can be taken as
"nil-reference".

Conforming to
-------------

   `Null' is a Borland Delphi extension.

Example
-------

     program NullDemo;
     type
       PString = ^String;
     var
       Com1: String (25) = 'This is an amazing number';
       Com2: String (25) = 'This is a boring number';
     
     procedure FooBar (Foo: Integer; var Comment: PString);
     begin
       if Odd (Foo) then
         WriteLn ('FooBar:', Foo, ' is odd')
        else
         WriteLn ('FooBar:', Foo, ' is even');
       if @Comment <> nil then
         if not Odd(foo) then
           Comment := @Com1
         else
           Comment := @Com2
     end;
     
     var
       S: String (25);
       P: PString value @S;
     
     begin
       { FooBar allows you to leave out variables
         for any information you might not need }
       FooBar (1, Null);
       { But FooBar is flexible, after all }
       FooBar (6, p);
       WriteLn ('FooBar said about 6: `', P^, '''')
     end.

See also
--------

   *Note nil::


File: gpc,  Node: object,  Next: Odd,  Prev: Null,  Up: Reference

object
======

Synopsis
--------

Description
-----------

   The keyword `object' is used to declare a new object type:

     type
       foo = object
         a: Integer;
         constructor Init;
         procedure Bar (x: Integer); virtual;
       end;

   (For a longer example, see *Note OOP::.)

Conforming to
-------------

   GNU Pascal follows the Borland Pascal 7.0 object model.

   ISO Pascal does not support Object-orientated programming. There is
an ANSI draft for an "Object Pascal" language which is not yet
supported by GPC, but planned. The Delphi language, also called "Object
Pascal" by Borland, is currently not supported by GPC either.

Example
-------

See also
--------

   *Note OOP::, *Note record::.


File: gpc,  Node: Odd,  Next: of,  Prev: object,  Up: Reference

Odd
===

Synopsis
--------

     function Odd (i: Integer): Boolean;

Description
-----------

   `Odd' checks the parity of its argument `i'. It returns `True' if
the argument is odd, `False' if it is even.

Conforming to
-------------

   `Odd' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

     program OddDemo;
     var
       Foo: Integer;
     begin
       Write ('Please enter an odd number: ');
       ReadLn (Foo);
       if not Odd (Foo) then
         WriteLn ('Odd''s not even! Something''s odd out there ...')
       else
         WriteLn (Foo, ' is pretty odd.')
     end.

See also
--------


File: gpc,  Node: of,  Next: only,  Prev: Odd,  Up: Reference

of
==

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: only,  Next: operator,  Prev: of,  Up: Reference

only
====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: operator,  Next: or,  Prev: only,  Up: Reference

operator
========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: or,  Next: or else,  Prev: operator,  Up: Reference

or
==

Synopsis
--------

     operator or (operand1, operand2: Boolean) = Result: Boolean;
   or
     operator or (operand1, operand2: INTEGER TYPE) = Result: INTEGER TYPE;
   or
     procedure or (var operand1: INTEGER TYPE; operand2: INTEGER TYPE);

Description
-----------

   In GNU Pascal, `or' has three built-in meanings:

  1. Logical "or" between two `Boolean'-type expressions.  The result
     of the operation is of `Boolean' type.

     By default, `or' acts as a short-circuit operator in GPC:  If the
     first operand is `True', the second operand is not evaluated
     because the result is already known to be `True'.  You can change
     this to complete evaluation using the `--no-short-circuit'
     command-line option or the `{$B+}' compiler directive.

  2. Bitwise "or" between two integer-type expressions.  The result is
     of the common integer type of both expressions.

  3. Use as a "procedure":  `operand1' is "or"ed bitwise with
     `operand2'; the result is stored in `operand1'.


Conforming to
-------------

   The logical `or' operator is defined in ISO-7185 Standard Pascal.

   According to ISO, you cannot rely on `or' being a short-circuit
operator. On the other hand, GPC's default behaviour does _not_
contradict the ISO standard. (See *Note or_else::.) However, since it
seems to be a de-facto standard among ISO Pascal compilers to evaluate
both operands of `or', GPC switches to `--no-short-circuit' mode if one
of the language dialect options selecting ISO Pascal, for instance
`--extended-pascal', is given. Use `--short-circuit' to override.

   Use of `or' as a bitwise operator for integers is a Borland Pascal
extension.

   Use of `or' as a "procedure" is a GNU Pascal extension.

Example
-------

     program OrDemo;
     var
       a, b, c: Integer;
     begin
       if (a = 0) or (b = 0) then  { logical `or' }
         c := 1
       else if a or b = 0 then  { bitwise `or' }
         c := 2
       else
         or (c, a)  { same as `c := c or a' }
     end.

   Note the difference between the logical `or' and the bitwise `or':
When `a' is 2 and `b' is 4, then `a or b' is 6. *Beware:* `a or b = 0'
happens to mean the same as `(a = 0) and (b = 0)'. (Note the `and'!)

   Since bitwise `or' has a higher priority than the `=' operator,
parentheses are needed in `if (a = 0) or (b = 0)' because otherwise `0
or b' would be calculated first, and the remainder would cause a parse
error.

See also
--------

   *Note and::, *Note xor::, *Note Operators::.


File: gpc,  Node: or else,  Next: Ord,  Prev: or,  Up: Reference

or else
=======

Synopsis
--------

     { `or else' is built in. A user-defined operator cannot consist of
        two words. }
     operator or else (operand1, operand2: Boolean) = Result: Boolean;

Description
-----------

   `or else' is an alias for the short-circuit logical operator
`or_else'.

Conforming to
-------------

   While `or_else' is defined in ISO-10206 Extended Pascal, `or else'
is a GNU Extension.

Example
-------

     program OrElseDemo;
     var
       a: Integer;
     begin
       ReadLn (a);
       if (a = 0) or else (100 div a > 42) then  { This is safe. }
         WriteLn ('100 div a > 42')
     end.

See also
--------

   *Note or_else::, *Note or::, *Note and then::.


File: gpc,  Node: Ord,  Next: or_else,  Prev: or else,  Up: Reference

Ord
===

   (Under construction.)

Synopsis
--------

     function Ord (Ch: Char): Integer;

Description
-----------

Conforming to
-------------

   `Ord' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

See also
--------


File: gpc,  Node: or_else,  Next: otherwise,  Prev: Ord,  Up: Reference

or_else
=======

Synopsis
--------

     operator or_else (operand1, operand2: Boolean) = Result: Boolean;

Description
-----------

   The `or_else' short-circuit logical operator performs the same
operation as the logical operator `or'. But while the ISO standard does
not specify anything about the evaluation of the operands of `or' -
they may be evaluated in any order, or not at all - `or_else' has a
well-defined behaviour: It evaluates the first operand. If the result
is `True', `or_else' returns `True' without evaluating the second
operand. If it is `False', the second operand is evaluated and returned.

   GPC by default treats `or' and `or_else' exactly the same.  If you
want, for some reason, to have both operands of `or' evaluated
completely, you must assign both to temporary variables and then use
`or' - or `or_else', it does not matter.

Conforming to
-------------

   `or_else' is an ISO-10206 Extended Pascal extension.

   Some people think that the ISO standard requires both operands of
`or' to be evaluated. This is false. What the ISO standard _does_ say
is that you cannot rely on a certain order of evaluation of the
operands of `or'; in particular things like the following program can
crash according to ISO Pascal, although they cannot crash when compiled
with GNU Pascal running in default mode.

     program OrBug;
     var
       a: Integer;
     begin
       ReadLn (a);
       if (a = 0) or (100 div a > 42) then  { This is NOT safe! }
         WriteLn ('You''re lucky. But the test could have crashed...')
     end.

Example
-------

     program Or_ElseDemo;
     var
       a: Integer;
     begin
       ReadLn (a);
       if (a = 0) or_else (100 div a > 42) then  { This is safe. }
         WriteLn ('100 div a > 42')
     end.

See also
--------

   *Note or else::, *Note or::, *Note and_then::.


File: gpc,  Node: otherwise,  Next: Output,  Prev: or_else,  Up: Reference

otherwise
=========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Output,  Next: Override,  Prev: otherwise,  Up: Reference

Output
======

   (Under construction.)

Synopsis
--------

     var
       Output: Text;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Override,  Next: Pack,  Prev: Output,  Up: Reference

Override
========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Pack,  Next: packed,  Prev: Override,  Up: Reference

Pack
====

   (Under construction.)

Synopsis
--------

Description
-----------

     procedure Pack (Source: UNPACKED ARRAY;
                     FirstElement: INDEX TYPE;
                     var Dest: PACKED ARRAY);

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: packed,  Next: Page,  Prev: Pack,  Up: Reference

packed
======

Synopsis
--------

Description
-----------

   `packed' is a reserved word. According to ISO-7185 Standard Pascal
it can precede `array' and `record' type definitions to indicate that
memory usage should be minimized for variables of this type, possibly
at the expense of loss of speed.

   As a GNU extension, `packed' can also be applied to *Note Subrange
Types::.

Conforming to
-------------

   The reserved word `packed' is defined in ISO-7185 Standard Pascal.

   According to ISO standard, only _packed_ arrays of char with lower
bound 1 qualify as strings of fixed length. GNU Pascal neither requires
`packed' nor the lower bound of 1 here.

Example
-------

     program PackedDemo;
     
     type
       MonthInt = packed 1 .. 12;  { needs one byte   }
       FastMonthInt = 1 .. 12;     { needs four bytes }
     
       FixString10 = packed array [1 .. 10] of Char;
       FoxyString10 = array [0 .. 9] of Char;
     
       Flags = packed array [1 .. 32] of Boolean;  { needs four Bytes }
     
       DateRec = packed record
         Day: 1 .. 31;       { five bits }
         Month: MonthInt;    { four bits }
         Year: Integer (15)  { 15 bits = -16384 .. 16383 }
       end;
     
       Dates = array [1 .. 1000] of DateRec;
     
     var
       S: FixString10;
       T: FoxyString10;
     
     begin
       S := 'Hello!';   { blank padded }
       WriteLn (S);
     
       T := 'GNU Pascal';  { GPC extension: this also works. }
       WriteLn (T)
     end.

   `DateRec' has 24 bits = 3 bytes in total; `Dates' has 3000 bytes.

See also
--------

   *Note Pack::, *Note Unpack::, *Note SizeOf::, *Note AlignOf::, *Note
BitSizeOf::.


File: gpc,  Node: Page,  Next: PAnsiChar,  Prev: packed,  Up: Reference

Page
====

   (Under construction.)

Synopsis
--------

     procedure Page (var F: Text);
   or
     procedure Page;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: PAnsiChar,  Next: ParamCount,  Prev: Page,  Up: Reference

PAnsiChar
=========

   (Under construction.)

Synopsis
--------

     type
       PAnsiChar = ^AnsiChar;

Description
-----------

Conforming to
-------------

Example
-------

     program PAnsiCharDemo;
     var
       s: PAnsiChar;
     begin
       s := 'Hello, world!';
       {$X+}
       WriteLn (s)
     end.

See also
--------


File: gpc,  Node: ParamCount,  Next: ParamStr,  Prev: PAnsiChar,  Up: Reference

ParamCount
==========

Synopsis
--------

     function ParamCount: Integer;

Description
-----------

   `ParamCount' returns the number of command-line arguments given to
the program.  `ParamCount' returns 0 if no arguments have been given to
the program; the name of the program as an implicit argument is not
counted.

Conforming to
-------------

   `ParamCount' is a Borland Pascal extension.

Example
-------

     program ParamCountDemo;
     
     var
       i: Integer;
     
     begin
       WriteLn ('You have invoked this program with ',
                ParamCount, ' arguments.');
       WriteLn ('These are:');
       for i := 1 to ParamCount do
         WriteLn (ParamStr (i))
     end.

See also
--------

   *Note ParamStr::.


File: gpc,  Node: ParamStr,  Next: PChar,  Prev: ParamCount,  Up: Reference

ParamStr
========

   (Under construction.)

Synopsis
--------

     function ParamStr (ParmNumber: Integer): String;

Description
-----------

   *Note:* If you are using the Dos (DJGPP) or MS-Windows (mingw32)
version of GPC and are getting unexpected results from `ParamStr',
please see the section "Command-line Arguments Handling in DJGPP" of
the DJGPP FAQ list.

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: PChar,  Next: Pi,  Prev: ParamStr,  Up: Reference

PChar
=====

   (Under construction.)

Synopsis
--------

     type
       PChar = ^Char;
   or
     type
       PChar = CString;

Description
-----------

Conforming to
-------------

Example
-------

     program PCharDemo;
     var
       s: PChar;
     begin
       s := 'Hello, world!';
       {$X+}
       WriteLn (s)
     end.

See also
--------


File: gpc,  Node: Pi,  Next: Pointer,  Prev: PChar,  Up: Reference

Pi
==

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Pointer,  Next: Polar,  Prev: Pi,  Up: Reference

Pointer
=======

   (Under construction.)

Synopsis
--------

     type
       Pointer  { built-in type }

Description
-----------

Conforming to
-------------

Example
-------

     program PointerDemo;
     var
       a: Integer;
       b: Boolean;
       p: Pointer;
     begin
       p := nil;
       p := @a;
       p := @b
     end.

See also
--------


File: gpc,  Node: Polar,  Next: Pos,  Prev: Pointer,  Up: Reference

Polar
=====

   (Under construction.)

Synopsis
--------

     function Polar (rho, phi: Real): Complex;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Pos,  Next: Position,  Prev: Polar,  Up: Reference

Pos
===

   (Under construction.)

Synopsis
--------

     function Pos (SearchPattern, Source: String): Integer;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Position,  Next: pow,  Prev: Pos,  Up: Reference

Position
========

   (Under construction.)

Synopsis
--------

     function Position (var F: TYPED FILE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: pow,  Next: Pred,  Prev: Position,  Up: Reference

pow
===

   (Under construction.)

Synopsis
--------

     operator pow (base: Real; exponent: Integer) = power: Real;
   or
     operator pow (base: Complex; exponent: Integer) = power: Complex;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Pred,  Next: private,  Prev: pow,  Up: Reference

Pred
====

Synopsis
--------

     function Pred (i: ORDINAL TYPE): ORDINAL TYPE;
   or
     function Pred (i: ORDINAL TYPE; j: Integer): ORDINAL TYPE;

   or, with extended syntax (`--extended-syntax' or `{$X+}'),

     function Pred (p: POINTER TYPE): POINTER TYPE;
   or
     function Pred (p: POINTER TYPE; j: Integer): POINTER TYPE;

Description
-----------

   Returns the predecessor of the ORDINAL TYPE value `i', or, if the
second argument `j' is given, its `j'th predecessor.  For integer
values `i', this is `i - 1' (or `i - j').  (No, `Pred' does _not_ work
faster than plain subtraction.  Both are optimized to a single machine
instruction or even expanded by the compiler, if possible.)

   If extended syntax is on, the argument may also be a pointer value.
In this case, the address is decremented by the size of the variable
pointed to, or, if `j' is given, by `j' times the size of the variable
pointed to.  If `p' points to an element of an array, the returned
pointer will point to the (`j'th) previous element of the array.

Conforming to
-------------

   The `Pred' function is defined in ISO-7185 Standard Pascal.  The
optional second parameter is defined in ISO-10206 Extended Pascal.
Application of `Pred' to pointers is defined in Borland Pascal.  The
combination of the second argument with application to pointers is a
GNU extension.

Example
-------

     program PredDemo;
     
     type
       Metasyntactical = (foo, bar, baz);
     
     var
       m: Metasyntactical;
       c: Char;
       a: array [1 .. 7] of Integer;
       p: ^Integer;
     
     begin
       m := Pred (bar);     { foo }
       c := Pred ('Z', 2);  { 'X' }
       a [1] := 42;
       a [4] := Pred (a [1]);     { 41 }
       a [5] := Pred (a [4], 3);  { 38 }
       {$X+}
       p := @a [5];
       p := Pred (p);     { now p points to a [4] }
       p := Pred (p, 3);  { now p points to a [1] }
     end.

See also
--------

   *Note Succ::, *Note Dec::, *Note Pointer Arithmetics::.


File: gpc,  Node: private,  Next: procedure,  Prev: Pred,  Up: Reference

private
=======

   (Under construction.)

Synopsis
--------

Description
-----------

   GPC currently accepts but ignores the `private' directive in object
type declarations.

Conforming to
-------------

Example
-------

See also
--------

   *Note protected::, *Note public::, *Note published::.


File: gpc,  Node: procedure,  Next: program,  Prev: private,  Up: Reference

procedure
=========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: program,  Next: property,  Prev: procedure,  Up: Reference

program
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: property,  Next: protected,  Prev: program,  Up: Reference

property
========

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: protected,  Next: PtrCard,  Prev: property,  Up: Reference

protected
=========

   (Under construction.)

Synopsis
--------

Description
-----------

   The Extended Pascal meaning of `protected' is supported by GPC.

   GPC currently accepts but ignores the `protected' directive in
object type declarations.

Conforming to
-------------

   Extended Pascal and Borland Pascal, but with different meanings.

Example
-------

See also
--------

   *Note const::, *Note import::, *Note private::, *Note public::,
*Note published::.


File: gpc,  Node: PtrCard,  Next: PtrDiffType,  Prev: protected,  Up: Reference

PtrCard
=======

   (Under construction.)

Synopsis
--------

     type
       PtrCard = Cardinal (BitSizeOf (Pointer));

Description
-----------

Conforming to
-------------

Example
-------

     program PtrCardDemo;
     var
       a: PtrCard;
       p: Pointer;
     begin
       New (p);
       a := PtrCard (p);
       Inc (a);
       p := Pointer (a)
     end.

See also
--------


File: gpc,  Node: PtrDiffType,  Next: PtrInt,  Prev: PtrCard,  Up: Reference

PtrDiffType
===========

   (Under construction.)

Synopsis
--------

     type
       PtrDiffType  { built-in type }

Description
-----------

Conforming to
-------------

Example
-------

     program PtrDiffTypeDemo;
     var
       a: array [1 .. 10] of Integer;
       d: PtrDiffType;
       p, q: Pointer;
     begin
       p := @a [1];
       q := @a [4];
       {$X+}
       d := q - p
     end.

See also
--------


File: gpc,  Node: PtrInt,  Next: PtrWord,  Prev: PtrDiffType,  Up: Reference

PtrInt
======

   (Under construction.)

Synopsis
--------

     type
       PtrCard = Integer (BitSizeOf (Pointer));

Description
-----------

Conforming to
-------------

Example
-------

     program PtrIntDemo;
     var
       a: PtrInt;
       p: Pointer;
     begin
       New (p);
       a := PtrInt (p);
       Inc (a);
       p := Pointer (a)
     end.

See also
--------


File: gpc,  Node: PtrWord,  Next: public,  Prev: PtrInt,  Up: Reference

PtrWord
=======

   (Under construction.)

Synopsis
--------

     type
       PtrWord = PtrCard;

Description
-----------

Conforming to
-------------

Example
-------

     program PtrWordDemo;
     var
       a: PtrWord;
       p: Pointer;
     begin
       New (p);
       a := PtrWord (p);
       Inc (a);
       p := Pointer (a)
     end.

See also
--------


File: gpc,  Node: public,  Next: published,  Prev: PtrWord,  Up: Reference

public
======

   (Under construction.)

Synopsis
--------

Description
-----------

   GPC currently accepts but ignores the `public' directive in object
type declarations.

Conforming to
-------------

Example
-------

See also
--------

   *Note private::, *Note protected::, *Note published::.


File: gpc,  Node: published,  Next: Put,  Prev: public,  Up: Reference

published
=========

   (Under construction.)

Synopsis
--------

Description
-----------

   GPC currently accepts but ignores the `published' directive in
object type declarations.

Conforming to
-------------

Example
-------

See also
--------

   *Note private::, *Note protected::, *Note public::.


File: gpc,  Node: Put,  Next: qualified,  Prev: published,  Up: Reference

Put
===

   (Under construction.)

Synopsis
--------

     procedure Put (var F: TYPED FILE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: qualified,  Next: Random,  Prev: Put,  Up: Reference

qualified
=========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Random,  Next: Randomize,  Prev: qualified,  Up: Reference

Random
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Randomize,  Next: Re,  Prev: Random,  Up: Reference

Randomize
=========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Re,  Next: Read,  Prev: Randomize,  Up: Reference

Re
==

Synopsis
--------

     function Re (z: Complex): Real;

Description
-----------

   `Re' extracts the real part of the complex number `z'.

Conforming to
-------------

   `Re' is an ISO-10206 Extended Pascal extension.

Example
-------

     program ReDemo;
     var
       z: Complex;
     begin
       z := Cmplx (1, 2);
       WriteLn (Re (z) : 0 : 5)
     end.

See also
--------

   *Note Cmplx::, *Note Im::, *Note Arg::


File: gpc,  Node: Read,  Next: ReadLn,  Prev: Re,  Up: Reference

Read
====

   (Under construction.)

Synopsis
--------

     procedure Read (var F: TYPED FILE; VARIABLE);
   or
     procedure Read (var F: Text; VARIABLES);
   or
     procedure Read (VARIABLES);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: ReadLn,  Next: ReadStr,  Prev: Read,  Up: Reference

ReadLn
======

   (Under construction.)

Synopsis
--------

     procedure ReadLn (var F: Text; VARIABLES);
   or
     procedure ReadLn (VARIABLES);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: ReadStr,  Next: Real,  Prev: ReadLn,  Up: Reference

ReadStr
=======

   (Under construction.)

Synopsis
--------

     procedure ReadStr (const S: String; VARIABLES);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Real,  Next: record,  Prev: ReadStr,  Up: Reference

Real
====

   (Under construction.)

Synopsis
--------

     type
       Real  { built-in type }

Description
-----------

Conforming to
-------------

Example
-------

     program RealDemo;
     var
       a: Real;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------


File: gpc,  Node: record,  Next: register,  Prev: Real,  Up: Reference

record
======

Synopsis
--------

   In type definitions:
     RECORD TYPE IDENTIFIER = record
       FIELD IDENTIFIER : TYPE DEFINITION
       ...
       FIELD IDENTIFIER : TYPE DEFINITION
     end;

   or, with a variant part,

     RECORD TYPE IDENTIFIER = record
       FIELD IDENTIFIER : TYPE DEFINITION
       ...
       FIELD IDENTIFIER : TYPE DEFINITION
       case bar: VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
     end;

   or, without a variant selector field,

     RECORD TYPE IDENTIFIER = record
       FIELD IDENTIFIER : TYPE DEFINITION
       ...
       FIELD IDENTIFIER : TYPE DEFINITION
       case VARIANT TYPE of
         SELECTOR: (FIELD DECLARATIONS);
         SELECTOR: (FIELD DECLARATIONS);
         ...
     end;

Description
-----------

   The reserved word `record' starts the definition of a new record
type.

   Records can be `packed' to save memory usage at the expense of speed.

   The variants of a variant record may - but are not required to -
share one location in memory (inside the record).

   Sometimes variant records are used to emulate type casting in
ISO-7185 Standard Pascal. This is in fact a violation of the standard
and not portable. There is intentionally _no_ possibility in ISO-7185
Standard Pascal to emulate type casting.

Conforming to
-------------

   The reserved word `record' and record types are defined in ISO-7185
Standard Pascal.

   According to ISO Pascal, the variant type must be an identifier.
GNU Pascal, like UCSD and Borland Pascal, also allows a subrange here.

   Subranges in the variant fields, e.g. `case Integer of 2 .. 5', are
a GPC extension.

Example
-------

     program RecordDemo;
     
     type
       FooPtr = ^Foo;
     
       Foo = record
         Bar: Integer;
         NextFoo: fooPtr;
         case Choice: 1 .. 3 of
           1: (a: Integer);  { These three choices may share }
           2: (b: Real);     { one location in memory. }
           3: (c: Char;
               d: Boolean);
       end;
     
       SmallFoo = packed record
         b: 0 .. 3;
         a: Integer (5);
         r: Boolean
       end;  { needs 1 byte }
     
     var
       f: Foo;
     
     begin
       f.b := 3.14;
       WriteLn (f.a)  { yields some strange number which is part of the   }
                      { internal representation of the real number `f.b'. }
     end.

See also
--------

   *Note packed::, *Note case Statement::


File: gpc,  Node: register,  Next: Release,  Prev: record,  Up: Reference

register
========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Release,  Next: Rename,  Prev: register,  Up: Reference

Release
=======

   (Under construction.)

Synopsis
--------

     procedure Release (P: Pointer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Rename,  Next: repeat,  Prev: Release,  Up: Reference

Rename
======

   (Under construction.)

Synopsis
--------

     procedure Rename (var F: ANY FILE; NewName: String);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: repeat,  Next: Reset,  Prev: Rename,  Up: Reference

repeat
======

Synopsis
--------

     repeat
       STATEMENT;
       ...
       STATEMENT;
     until BOOLEAN EXPRESSION;

Description
-----------

   The `repeat ... until' statement declares a loop.  For further
description see *Note repeat Statement::.

Conforming to
-------------

   `repeat' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

     program RepeatDemo;
     var
       Number, Sum: Integer;
     begin
       WriteLn ('Black Jack for beginners.');
       WriteLn ('You can choose your cards yourself. :-)');
       Sum := 0;
       repeat
         Write ('Your card? ');
         ReadLn (Number);
         Inc (Sum, Number);
         WriteLn ('You have ', Sum, '.')
       until Sum >= 21;
       if Sum = 21 then
         WriteLn ('You win!')
       else
         WriteLn ('You lose.')
     end.

See also
--------

   *Note while Statement::, *Note for Statement::


File: gpc,  Node: Reset,  Next: resident,  Prev: repeat,  Up: Reference

Reset
=====

   (Under construction.)

Synopsis
--------

     procedure Reset (var F: ANY FILE);
   or
     procedure Reset (var F: ANY FILE; FileName: String);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: resident,  Next: restricted,  Prev: Reset,  Up: Reference

resident
========

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: restricted,  Next: Result,  Prev: resident,  Up: Reference

restricted
==========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Result,  Next: Return,  Prev: restricted,  Up: Reference

Result
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Return,  Next: ReturnAddress,  Prev: Result,  Up: Reference

Return
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: ReturnAddress,  Next: Rewrite,  Prev: Return,  Up: Reference

ReturnAddress
=============

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Rewrite,  Next: RmDir,  Prev: ReturnAddress,  Up: Reference

Rewrite
=======

   (Under construction.)

Synopsis
--------

     procedure Rewrite (var F: ANY FILE);
   or
     procedure Rewrite (var F: ANY FILE; FileName: String);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: RmDir,  Next: Root,  Prev: Rewrite,  Up: Reference

RmDir
=====

Synopsis
--------

     procedure RmDir (Directory: String);

Description
-----------

   `RmDir' removes the given DIRECTORY if its argument is a valid
parameter to the related operating system's function. Otherwise a
runtime error is caused.

Conforming to
-------------

   `RmDir' is a Borland Pascal extension.

Example
-------

     program RmDirDemo;
     var
       Foo: String (127);
     begin
       WriteLn ('Enter directory name to remove: ');
       ReadLn (Foo);
       {$i-}                     { Suppress exit on error }
       RmDir (Foo);
       if IOResult <> 0 then
         WriteLn ('Directory ', foo, ' could not be removed.')
       else
         WriteLn ('Okay.')
     end.

See also
--------

   *Note ChDir::, *Note MkDir::


File: gpc,  Node: Root,  Next: Round,  Prev: RmDir,  Up: Reference

Root
====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Round,  Next: RunError,  Prev: Root,  Up: Reference

Round
=====

Synopsis
--------

     function Round (x: Real): Integer;

Description
-----------

   `Round' returns the nearest integer to `x'. The result is of type
integer. In the case of equidistance, the result is machine-dependent
(or depends on the behaviour of the processor).

Conforming to
-------------

   `Round' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

     program RoundDemo;
     var
       Foo: Real;
     begin
       foo := 9.876543;
       WriteLn (Round (Foo));  { Prints 10 }
       foo := 3.456789;
       WriteLn (Round (Foo))   { Prints 3 }
     end.

See also
--------

   *Note Round::


File: gpc,  Node: RunError,  Next: Seek,  Prev: Round,  Up: Reference

RunError
========

   (Under construction.)

Synopsis
--------

     procedure RunError (ErrorCode: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Seek,  Next: SeekRead,  Prev: RunError,  Up: Reference

Seek
====

   (Under construction.)

Synopsis
--------

     procedure Seek (var F: TYPED FILE; NewPosition: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: SeekRead,  Next: SeekUpdate,  Prev: Seek,  Up: Reference

SeekRead
========

   (Under construction.)

Synopsis
--------

     procedure SeekRead (var F: TYPED FILE; NewPosition: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: SeekUpdate,  Next: SeekWrite,  Prev: SeekRead,  Up: Reference

SeekUpdate
==========

   (Under construction.)

Synopsis
--------

     procedure SeekUpdate (var F: TYPED FILE; NewPosition: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: SeekWrite,  Next: segment,  Prev: SeekUpdate,  Up: Reference

SeekWrite
=========

   (Under construction.)

Synopsis
--------

     procedure SeekWrite (var F: TYPED FILE; NewPosition: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: segment,  Next: Self,  Prev: SeekWrite,  Up: Reference

segment
=======

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Self,  Next: set,  Prev: segment,  Up: Reference

Self
====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: set,  Next: SetFileTime,  Prev: Self,  Up: Reference

set
===

   (Under construction.)

Synopsis
--------

   In type definitions:
     set of TYPE  { built-in type class }

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: SetFileTime,  Next: SetLength,  Prev: set,  Up: Reference

SetFileTime
===========

     procedure SetFileTime (var f : ANY FILE;
                            AccessTime, ModificationTime : UnixTimeType);

Synopsis
--------

Description
-----------

Conforming to
-------------

   `SetFileTime' is a GNU extension.

Example
-------

See also
--------


File: gpc,  Node: SetLength,  Next: SetType,  Prev: SetFileTime,  Up: Reference

SetLength
=========

Synopsis
--------

     procedure SetLength (var S: String; NewLength: Integer);

Description
-----------

   `SetLength' explicitly assigns a new length `NewLength' to the
string parameter `S'.  The contents of the string is _not_ changed; if
the operation increases the length of the string, the characters
appended at the end are _undefined_.

   If you want to use `SetLength', please enable "extended syntax"
(`--extended-syntax' or `{$X+}').

Conforming to
-------------

   `SetLength' is a Borland Delphi 2.0 extension.

Example
-------

     program SetLengthDemo;
     
     {$X+}  { Enable "dangerous" features }
     
     var
       S : String (26);
     
     begin
       S := 'Hello, world!';
       SetLength (S, Length ('Hello'));
       WriteLn (S);                                     { 'Hello' }
       SetLength (S, 26);
       WriteLn (S);               { 'Hello, world!(%$xy"!#&~+(/]' }
                           { undefined characters ^^^^^^^^^^^^^^  }
     
       SetLength (S, 42);  { The overflow is *not* (yet) detected }
       WriteLn (S);        { This might cause a runtime error.    }
     end.

See also
--------

   *Note Length::, *Note String::, *Note SetType::.


File: gpc,  Node: SetType,  Next: shl,  Prev: SetLength,  Up: Reference

SetType
=======

Synopsis
--------

     procedure SetType (var SomeObject; VMT: Pointer);

Description
-----------

   The procedure `SetType' explicitly assigns a value to the implicit
VMT field of an object.  This is normally done implicitly when a
constructor is called.

   You can use this to write a polymorphic I/O routine which reads an
object from a file.  In this case, you cannot reasonably use `New' to
allocate the storage, but you `GetMem' it and initialize the object
manually using `SetType' before calling the constructor explicitly.

   This is a dangerous feature which yields a warning unless `{$X+}' is
given.

Conforming to
-------------

   `SetType' is a GNU extension.

Example
-------

     program SetTypeDemo;
     
     type
       BasePtr = ^BaseObj;
     
       BaseObj = object
         constructor Load;
       end;
     
       ChildObj = object (BaseObj)
         constructor Load;
       end;
     
     constructor BaseObj.Load;
     begin
     end;
     
     constructor ChildObj.Load;
     begin
     end;
     
     {$X+}
     
     { This is somewhat fragmentary code. }
     function GetObject (var InputFile: File) = Result: BasePtr;
     const
       VMTTable: array [1 .. 2] of Pointer =
         (TypeOf (BaseObj), TypeOf (ChildObj));
     var
       Size: Cardinal;
       TypeID: Integer;
       VMT: Pointer;
     begin
       { Read the size of the object from some file and store it in `Size'. }
       BlockRead (InputFile, Size, SizeOf (Size));
     
       { Allocate memory for the object. }
       GetMem (Result, Size);
     
       { Read some ID from some file. }
       BlockRead (InputFile, TypeID, SizeOf (TypeID));
     
       { Look up the `VMT' from some table. }
       { Range checking wouldn't be a bad idea here... }
       VMT := VMTTable [TypeID];
     
       SetType (Result^, VMT);
     
       { Now the object is ready, and the constructor can be called. }
       { Look up the correct constructor from some table and call it. }
     end;
     
     begin
     end.

See also
--------

   *Note TypeOf::, *Note OOP::.


File: gpc,  Node: shl,  Next: ShortBool,  Prev: SetType,  Up: Reference

shl
===

Synopsis
--------

     operator shl (operand1, operand2: INTEGER TYPE) = Result: INTEGER TYPE;
   or
     procedure shl (var operand1: INTEGER TYPE; operand2: INTEGER TYPE);

Description
-----------

   In GNU Pascal, `shl' has two built-in meanings:

  1. Bitwise shift left of an integer-type expression by another
     integer value.  The result is of the type of the first operand.

  2. Use as a "procedure":  `operand1' is shifted left by `operand2';
     the result is stored in `operand1'.


Conforming to
-------------

   `shl' is a Borland Pascal extension.

   Use of `shl' as a "procedure" is a GNU Pascal extension.

Example
-------

     program ShlDemo;
     var
       a: Integer;
     begin
       a := 1 shl 7;  { yields 128 = 2 pow 7 }
       shl (a, 4)  { same as `a := a shl 4' }
     end.

See also
--------

   *Note shr::, *Note Operators::.


File: gpc,  Node: ShortBool,  Next: ShortCard,  Prev: shl,  Up: Reference

ShortBool
=========

   (Under construction.)

Synopsis
--------

     type
       ShortBool = Boolean (BitSizeOf (ShortInt));

Description
-----------

Conforming to
-------------

Example
-------

     program ShortBoolDemo;
     var
       a: ShortBool;
     begin
       ShortInt (a) := 1;
       if a then WriteLn ('Ord (True) = 1')
     end.

See also
--------


File: gpc,  Node: ShortCard,  Next: ShortInt,  Prev: ShortBool,  Up: Reference

ShortCard
=========

Synopsis
--------

     type
       ShortCard = Cardinal (BitSizeOf (ShortInt));

Description
-----------

   `ShortCard' is an unsigned integer type which is not larger than
`Cardinal'.  On most platforms it is 16 bits wide and thus has a range
of `0..65535'.

   `ShortCard' in GNU Pascal is compatible to `short unsigned int' in
GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `ShortCard' is a GNU Pascal extension.

Example
-------

     program ShortCardDemo;
     var
       a: ShortCard;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: ShortInt,  Next: ShortReal,  Prev: ShortCard,  Up: Reference

ShortInt
========

Synopsis
--------

     type
       ShortInt  { built-in type }

Description
-----------

   `ShortInt' is a signed integer type which is not larger than
`Integer'.  On most platforms it is 16 bits wide and thus has a range
of `-32768..32767'.

   `ShortInt' in GNU Pascal is compatible to `short int' in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `ShortInt' is a Borland Pascal extension. In Borland Pascal,
`ShortInt' is an 8-bit signed integer type (`ByteInt' in GNU Pascal).

Example
-------

     program ShortIntDemo;
     var
       a: ShortInt;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: ShortReal,  Next: ShortWord,  Prev: ShortInt,  Up: Reference

ShortReal
=========

   (Under construction.)

Synopsis
--------

     type
       ShortReal  { built-in type }

Description
-----------

Conforming to
-------------

Example
-------

     program ShortRealDemo;
     var
       a: ShortReal;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------


File: gpc,  Node: ShortWord,  Next: shr,  Prev: ShortReal,  Up: Reference

ShortWord
=========

Synopsis
--------

     type
       ShortWord = ShortCard;

Description
-----------

   `ShortWord' is an unsigned integer type which is not larger than
`Word'.  On most platforms it is 16 bits wide and thus has a range of
of `0..65535'.  It is the same as *Note ShortCard::.

   `ShortWord' in GNU Pascal is compatible to `short unsigned int' in
GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `ShortWord' is a GNU Pascal extension.

   `ShortWord' in GNU Pascal essentially corresponds to `Word' in
Borland Pascal and Delphi where it is a 16-bit unsigned integer type.

Example
-------

     program ShortWordDemo;
     var
       a: ShortWord;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: shr,  Next: Sin,  Prev: ShortWord,  Up: Reference

shr
===

Synopsis
--------

     operator shr (operand1, operand2: INTEGER TYPE) = Result: INTEGER TYPE;
   or
     procedure shr (var operand1: INTEGER TYPE; operand2: INTEGER TYPE);

Description
-----------

   In GNU Pascal, `shr' has two built-in meanings:

  1. Bitwise shift right of an integer-type expression by another
     integer value.  The result is of the type of the first operand.

  2. Use as a "procedure":  `operand1' is shifted right by `operand2';
     the result is stored in `operand1'.


Conforming to
-------------

   `shr' is a Borland Pascal extension.

   Unlike the Borland compilers, GNU Pascal cares about the signedness
of the first operand:  If a signed integer with a negative value is
shifted right, "one" bits are filled in from the left.

   Use of `shr' as a "procedure" is a GNU Pascal extension.

Example
-------

     program ShrDemo;
     var
       a: Integer;
     begin
       a := 1024 shr 4;  { yields 64 }
       a := -127 shr 4;  { yields -8 }
       shr (a, 2)  { same as `a := a shr 2' }
     end.

See also
--------

   *Note shl::, *Note Operators::.


File: gpc,  Node: Sin,  Next: Single,  Prev: shr,  Up: Reference

Sin
===

Synopsis
--------

     function Sin (x: Real): Real;
   or
     function Sin (z: Complex): Complex;

Description
-----------

   `Sin' returns the sine of the argument.  The result is in the range
`-1 <= Sin (x) <= 1' for real arguments.

Conforming to
-------------

   The function `Sin' is defined in ISO-7185 Standard Pascal; its
application to complex values is defined in ISO-10206 Extended Pascal.

Example
-------

     program SinDemo;
     begin
       WriteLn (Sin (SqRt (2) / 2) : 0 : 5)
       { yields 0.5 since Sin (SqRt (2) /2) = 0.5 }
     end.

See also
--------

   *Note ArcTan::, *Note Cos::, *Note Ln::, *Note Arg::.


File: gpc,  Node: Single,  Next: SizeOf,  Prev: Sin,  Up: Reference

Single
======

   (Under construction.)

Synopsis
--------

     type
       Single = ShortReal;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: SizeOf,  Next: SizeType,  Prev: Single,  Up: Reference

SizeOf
======

Synopsis
--------

     function SizeOf (var x): SizeType;

Description
-----------

   Returns the size of a type or variable in bytes.

Conforming to
-------------

   `SizeOf' is an UCSD Pascal extension.

Example
-------

     program SizeOfDemo;
     var
       a: Integer;
       b: array [1 .. 8] of Char;
     begin
       WriteLn (SizeOf (a));  { Size of an `Integer'; often 4 bytes. }
       WriteLn (SizeOf (b))   { Size of eight `Char's; usually 8 bytes. }
     end.

See also
--------

   *Note BitSizeOf::, *Note AlignOf::, *Note TypeOf::.


File: gpc,  Node: SizeType,  Next: SmallInt,  Prev: SizeOf,  Up: Reference

SizeType
========

   (Under construction.)

Synopsis
--------

     type
       SizeType  { built-in type }

Description
-----------

Conforming to
-------------

Example
-------

     program SizeTypeDemo;
     var
       a: array [1 .. 10] of Integer;
       Size: SizeType;
     begin
       Size := SizeOf (a);
       WriteLn (Size)
     end.

See also
--------


File: gpc,  Node: SmallInt,  Next: Sqr,  Prev: SizeType,  Up: Reference

SmallInt
========

Synopsis
--------

     type
       SmallInt = ShortInt;

Description
-----------

   `SmallInt' is a signed integer type which is not larger than
`Integer'. On most platforms it is 16 bits wide and thus has a range of
`-32768..32767'. It is the same as `ShortInt' (see *Note ShortInt::).

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   `SmallInt' is a Delphi 2.0 extension.

Example
-------

     program SmallIntDemo;
     var
       a: SmallInt;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note ShortInt::, *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: Sqr,  Next: SqRt,  Prev: SmallInt,  Up: Reference

Sqr
===

Synopsis
--------

     function Sqr (i: INTEGER TYPE): INTEGER TYPE;
   or
     function Sqr (x: REAL TYPE): REAL TYPE;
   or
     function Sqr (z: COMPLEX TYPE): COMPLEX TYPE;

Description
-----------

   Returns the square of the argument:

     function Sqr (x: SOME TYPE): SOME TYPE;
     begin
       Sqr := x * x  { or: x pow 2 }
     end;

Conforming to
-------------

   The function `Sqr' is defined in ISO-7185 Standard Pascal; its
application to complex values is defined in ISO-10206 Extended Pascal.

Example
-------

     program SqrDemo;
     
     var
       i: Complex;
     
     begin
       i := Cmplx (0, 1);
       WriteLn (Re (Sqr (i)) : 0 : 3)  { yields -1.000 }
     end.

See also
--------

   *Note pow::, *Note SqRt::, *Note Abs::, *Note Operators::.


File: gpc,  Node: SqRt,  Next: StandardError,  Prev: Sqr,  Up: Reference

SqRt
====

Synopsis
--------

     function SqRt (x: REAL TYPE): REAL TYPE;
   or
     function SqRt (z: COMPLEX TYPE): COMPLEX TYPE;

Description
-----------

   Returns the positive square root of the argument.

   For real arguments, it is an error if the argument is negative.

   For complex arguments, `SqRt' returns the principal value of the
root of the argument, i.e. the root with positive real part, or, if the
real part is zero, that one with positive imaginary part.

Conforming to
-------------

   The function `SqRt' is defined in ISO-7185 Standard Pascal; its
application to complex values is defined in ISO-10206 Extended Pascal.

Example
-------

     program SqRtDemo;
     
     var
       m1: Complex;
     
     begin
       m1 := Cmplx (-1, 0);  { -1 }
       WriteLn (Re (SqRt (m1)) : 6 : 3, Im (SqRt (m1)) : 6 : 3);
         { yields 1.000 -1.000, i.e. the imaginary unit, i }
     end.

See also
--------

   *Note pow::, *Note Sqr::, *Note Operators::.


File: gpc,  Node: StandardError,  Next: StandardInput,  Prev: SqRt,  Up: Reference

StandardError
=============

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: StandardInput,  Next: StandardOutput,  Prev: StandardError,  Up: Reference

StandardInput
=============

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: StandardOutput,  Next: static,  Prev: StandardInput,  Up: Reference

StandardOutput
==============

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: static,  Next: StdErr,  Prev: StandardOutput,  Up: Reference

static
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: StdErr,  Next: Str,  Prev: static,  Up: Reference

StdErr
======

Synopsis
--------

     var
       StdErr: Text;

Description
-----------

   The `StdErr' variable is connected to the standard error file
handle. To report errors, you should prefer `WriteLn (StdErr,
'everything wrong')' over `WriteLn ('everything wrong')'.

Conforming to
-------------

   `StdErr' is a GNU Pascal extension.

Example
-------

     program StdErrDemo;
     var
       Denominator: Integer;
     begin
       ReadLn (Denominator);
       if Denominator = 0 then
         WriteLn (StdErr, ParamStr (0), ': division by zero')
       else
         WriteLn ('1 / ', Denominator, ' = ', 1 / Denominator)
     end.

See also
--------

   *Note StandardError::, *Note Output::, *Note Input::.


File: gpc,  Node: Str,  Next: String,  Prev: StdErr,  Up: Reference

Str
===

   (Under construction.)

Synopsis
--------

     procedure Str (x: INTEGER OR REAL; var Dest: String);
   or
     procedure Str (x: INTEGER OR REAL : FIELD WIDTH; var Dest: String);
   or
     procedure Str (x: Real : FIELD WIDTH : PRECISION; var Dest: String);
   or
     procedure Str (REPEATED CONSTRUCTS AS DESCRIBED ABOVE; var Dest: String);

Description
-----------

Conforming to
-------------

   `Str' is an UCSD Pascal extension, generalized by Borland Pascal.
The possibility to handle more than one variable with one call to `Str'
is a GNU Pascal extension.

   ISO-10206 Extended Pascal defines `WriteStr' instead of `Str'.

Example
-------

See also
--------

   *Note WriteStr::.


File: gpc,  Node: String,  Next: String2CString,  Prev: Str,  Up: Reference

String
======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: String2CString,  Next: SubStr,  Prev: String,  Up: Reference

String2CString
==============

   (Under construction.)

Synopsis
--------

     function String2CString (const S: String): CString;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: SubStr,  Next: Succ,  Prev: String2CString,  Up: Reference

SubStr
======

Synopsis
--------

     function SubStr (S: String; FirstChar: Integer): String;
   or
     function SubStr (S: String; FirstChar, Count: Integer): String;

Description
-----------

   `SubStr' returns a sub-string of S starting with the character at
position FIRSTCHAR.  If COUNT is given, such many characters will be
copied into the sub-string.  If COUNT is omitted, the sub-string will
will range to the end of S.

   If `Count' is too large for the sub-string to fit in S or if
`FirstChar' exceeds the length of S, `SubStr' triggers a runtime error.
(For a function returning the empty string instead, see *Note Copy::.)

Conforming to
-------------

   `SubStr' is a ISO 10206 Extended Pascal extension.

Example
-------

     program SubStrDemo;
     var
       S: String (42);
     begin
       S := 'Hello';
       WriteLn (SubStr (S, 2, 3));   { yields "ell" }
       WriteLn (SubStr (S, 3));      { yields "llo" }
       WriteLn (SubStr (S, 4, 7));   { yields a runtime error }
       WriteLn (SubStr (S, 42));     { yields a runtime error }
     end.

See also
--------

   *Note Copy::, String slice access.


File: gpc,  Node: Succ,  Next: Text,  Prev: SubStr,  Up: Reference

Succ
====

Synopsis
--------

     function Succ (i: ORDINAL TYPE): ORDINAL TYPE;
   or
     function Succ (i: ORDINAL TYPE; j: Integer): ORDINAL TYPE;

   or, with extended syntax (`--extended-syntax' or `{$X+}'),

     function Succ (p: POINTER TYPE): POINTER TYPE;
   or
     function Succ (p: POINTER TYPE; j: Integer): POINTER TYPE;

Description
-----------

   Returns the successor of the ORDINAL TYPE value `i', or, if the
second argument `j' is given, its `j'th successor.  For integer values
`i', this is `i + 1' (or `i + j').  (No, `Succ' does _not_ work faster
than plain addition.  Both are optimized to a single machine
instruction or even expanded by the compiler, if possible.)

   If extended syntax is on, the argument may also be a pointer value.
In this case, the address is incremented by the size of the variable
pointed to, or, if `j' is given, by `j' times the size of the variable
pointed to.  If `p' points to an element of an array, the returned
pointer will point to the (`j'th) next element of the array.

Conforming to
-------------

   The `Succ' function is defined in ISO-7185 Standard Pascal.  The
optional second parameter is defined in ISO-10206 Extended Pascal.
Application of `Succ' to pointers is defined in Borland Pascal.  The
combination of the second argument with application to pointers is a
GNU extension.

Example
-------

     program SuccDemo;
     
     type
       Metasyntactical = (foo, bar, baz);
     
     var
       m: Metasyntactical;
       c: Char;
       a: array [1 .. 7] of Integer;
       p: ^Integer;
     
     begin
       m := Succ (foo);     { bar }
       c := Succ ('A', 4);  { 'E' }
       a [1] := 42;
       a [2] := Succ (a [1]);     { 43 }
       a [5] := Succ (a [2], 7);  { 50 }
       {$X+}
       p := @a [1];
       p := Succ (p);     { points to `a [2]' now }
       p := Succ (p, 3);  { points to `a [5]' now }
     end.

See also
--------

   *Note Pred::, *Note Inc::, *Note Pointer Arithmetics::.


File: gpc,  Node: Text,  Next: TextWritable,  Prev: Succ,  Up: Reference

Text
====

   (Under construction.)

Synopsis
--------

     type
       Text  { built-in type }

Description
-----------

Conforming to
-------------

Example
-------

     program TextDemo;
     var
       t: Text;
     begin
       Rewrite (t, 'hello.txt');
       WriteLn (t, 'Hello, world!')
     end.

See also
--------


File: gpc,  Node: TextWritable,  Next: then,  Prev: Text,  Up: Reference

TextWritable
============

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: then,  Next: Time,  Prev: TextWritable,  Up: Reference

then
====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

     program ThenDemo;
     var
       i: Integer;
     begin
       Write ('Enter a number: ');
       ReadLn (i);
       if i > 42 then
         WriteLn ('The number is greater than 42')
     end.

See also
--------


File: gpc,  Node: Time,  Next: TimeStamp,  Prev: then,  Up: Reference

Time
====

   (Under construction.)

Synopsis
--------

     function Time (T: TimeStamp): packed array [1 .. TIME LENGTH] of Char;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: TimeStamp,  Next: to,  Prev: Time,  Up: Reference

TimeStamp
=========

   (Under construction.)

Synopsis
--------

     type
       TimeStamp = {@@packed} record
         DateValid,
         TimeValid   : Boolean;
         Year        : Integer;
         Month       : 1 .. 12;
         Day         : 1 .. 31;
         DayOfWeek   : 0 .. 6;  { 0 means Sunday }
         Hour        : 0 .. 23;
         Minute      : 0 .. 59;
         Second      : 0 .. 61; { to allow for leap seconds }
         MicroSecond : 0 .. 999999
       end;

   (@@ Currently, in GPC, TimeStamp is not actually packed.)

   All fields except DayOfWeek and MicroSecond are required by Extended
Pascal.

   @@ `TimeStamp' may be later extended in GPC to contain the following
additional fields:

     Dst_used   : Boolean;  { If daylight savings are used }
     TimeZone   : Integer;  { Positive if west, in minutes }
     TimerValid : Boolean;  { Is the following timer valid }
     us_Timer   : Integer;  { A microsecond timer that is a 32 bit
                               modulus of the timer returned by the system. }

   Fields `Dst_used, TimeZone' and `DayOfWeek' will be valid when
`DateValid' is `True'. Field `us_Timer' will be valid when `TimerValid'
is `True'.

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: to,  Next: to begin do,  Prev: TimeStamp,  Up: Reference

to
==

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: to begin do,  Next: to end do,  Prev: to,  Up: Reference

to begin do
===========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: to end do,  Next: Trim,  Prev: to begin do,  Up: Reference

to end do
=========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Trim,  Next: True,  Prev: to end do,  Up: Reference

Trim
====

   (Under construction.)

Synopsis
--------

     function Trim (S: String): String;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: True,  Next: Trunc,  Prev: Trim,  Up: Reference

True
====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Trunc,  Next: Truncate,  Prev: True,  Up: Reference

Trunc
=====

Synopsis
--------

     function Trunc (x: Real): Integer;

Description
-----------

   `Trunc' converts `x' to the next integer below its argument (i.e.
truncates the numbers after the point).

Conforming to
-------------

   `Trunc' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

     program TruncDemo;
     var
       Foo: Real;
     begin
       Foo := 9.876;
       WriteLn (Trunc (Foo))  { Prints 9 }
     end.

See also
--------

   *Note Round::.


File: gpc,  Node: Truncate,  Next: type,  Prev: Trunc,  Up: Reference

Truncate
========

   (Under construction.)

Synopsis
--------

     procedure Truncate (var F: ANY FILE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: type,  Next: type of,  Prev: Truncate,  Up: Reference

type
====

Synopsis
--------

   As a type declaration:
     type
       TYPE INDENTIFIER = TYPE DEFINITION;
   or with initialization:
     type
       TYPE INDENTIFIER = TYPE DEFINITION value CONSTANT EXPRESSION;

Description
-----------

   The reserved word `type' starts the declaration of a TYPE IDENTIFIER
which is defined by TYPE DEFINITION.  For further description see *Note
Type Declaration::, *Note Type Declaration::, *Note Type Definition::,
*Note Data Types::.

Conforming to
-------------

   `type' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants. Initializers are an ISO-10206 Extended Pascal
extension.

Example
-------

     program TypeDemo;
     type
       { This side is the }    { That side is the }
       { type declaration }    { type definition  }
     
       { array type }
       ArrayType                  = array [0 .. 9] of Integer;
     
       { record type }
       RecordType                 = record
                                      bar: Integer
                                    end;
     
       { subrange type }
       SubrangeType               = -123 .. 456;
     
       { enumeration type }
       EnumeratedType             = (Mon, Tue, Wed, Thu, Fri,  Sat, Sun);
     
       { set type }
       CharSetType                = set of Char;
     
       { object type }
       ObjectType                 = object
                                      constructor Init;
                                      procedure Method;
                                      destructor Done
                                    end;
     
       { pointer type to another type identifier }
       PArrayType                 = ^ArrayType;
     
       { an alias name for another type identifier }
       IntegerType                = Integer;
     
       { an integer which is initialized by 123 }
       InitializedInt             = Integer value 123;
     
       { a schema with discriminants x and y of type Integer }
       SchemaType (x, y: Integer) = array [x .. y] of Integer;
     
     begin
     end.

See also
--------

   *Note Type Declaration::, *Note Type Definition::, *Note Data
Types::, *Note Variable Declaration::, *Note array::, *Note record::,
*Note object::, *Note set::, *Note Pointer::, *Note value::.


File: gpc,  Node: type of,  Next: TypeOf,  Prev: type,  Up: Reference

type of
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: TypeOf,  Next: UnBind,  Prev: type of,  Up: Reference

TypeOf
======

Synopsis
--------

     function TypeOf (var x): Pointer;

Description
-----------

   Returns a pointer to the VMT of an _object_ type or variable.  This
pointer can be used to identify the type of an object.

Conforming to
-------------

   ISO Pascal does not define `TypeOf', Borland Pascal does.

Example
-------

     program TypeOfDemo;
     type
       FooPtr = ^Foo;
       BarPtr = ^Bar;
     
       Foo = object        { Has a VMT, though it doesn't }
         x: Integer;       { contain virtual methods.     }
         constructor Init;
       end;
     
       Bar = object (Foo)
         y: Integer;
       end;
     
     constructor Foo.Init;
     begin
     end;
     
     var
       MyFoo: FooPtr;
     
     begin
       MyFoo := New (BarPtr, Init);
       if TypeOf (MyFoo^) = TypeOf (bar) then  { True }
         WriteLn ('OK')
     end.

See also
--------

   *Note BitSizeOf::, *Note AlignOf::, *Note TypeOf::, *Note SetType::,
*Note OOP::.


File: gpc,  Node: UnBind,  Next: unit,  Prev: TypeOf,  Up: Reference

UnBind
======

   (Under construction.)

Synopsis
--------

     procedure UnBind (var F: ANY FILE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: unit,  Next: Unpack,  Prev: UnBind,  Up: Reference

unit
====

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Unpack,  Next: until,  Prev: unit,  Up: Reference

Unpack
======

   (Under construction.)

Synopsis
--------

     procedure Unpack (Source: PACKED ARRAY;
                       var Dest: UNPACKED ARRAY;
                       FirstElement: INDEX TYPE);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: until,  Next: UpCase,  Prev: Unpack,  Up: Reference

until
=====

   (Under construction.)

Synopsis
--------

Description
-----------

   `until' is part of the `repeat ... until' loop statement.

Conforming to
-------------

Example
-------

See also
--------

   *Note repeat::, *Note while::, *Note for::.


File: gpc,  Node: UpCase,  Next: Update,  Prev: until,  Up: Reference

UpCase
======

   (Under construction.)

Synopsis
--------

     function UpCase (Ch: Char): Char;

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Update,  Next: uses,  Prev: UpCase,  Up: Reference

Update
======

   (Under construction.)

Synopsis
--------

     procedure Update (var F: ANY FILE);
   or
     procedure Update (var F: ANY FILE; FileName: String);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: uses,  Next: Val,  Prev: Update,  Up: Reference

uses
====

Synopsis
--------

   In a program:

     program @@fragment foo;
     
     uses
       bar1,
       bar2 in 'baz.pas',
       bar3;
     
     [...]

   In a unit:

     unit @@fragment Bar3;
     
     interface
     
     uses
       bar1,
       bar2 in 'baz.pas';
     
     [...]
     
     implementation
     
     uses
       bar3,
       bar4 in 'qux.pas';
     
     [...]

Description
-----------

   The reserved word `uses' in the _import part_ of a program or unit
makes the program or unit import an interface.

   The keyword `in' tells GPC to look for the `unit' in the specified
file; otherwise the file name is derived from the name of the interface
by adding first `.p', then `.pas'.

   There must be at most one import part in a program.

   In a unit, there can be one import part in the interface part and
one in the implementation part.

   The imported interface needn't be an UCSD/Borland Pascal unit, it
may be an interface exported by an Extended Pascal module as well.

Conforming to
-------------

   ISO Pascal does not define `uses' and units at all. UCSD and Borland
Pascal do, but without the `in' extension. Delphi supports `uses' like
described above.

Example
-------

See also
--------

   *Note unit::, *Note module::, *Note import::.


File: gpc,  Node: Val,  Next: value,  Prev: uses,  Up: Reference

Val
===

   (Under construction.)

Synopsis
--------

     procedure Val (const Source: String; var x: INTEGER OR REAL);
   or
     procedure Val (const Source: String; var x: INTEGER OR REAL;
                    var ErrorCode: Integer);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: value,  Next: var,  Prev: Val,  Up: Reference

value
=====

Synopsis
--------

Description
-----------

   The reserved word `value' is part of a type or var declaration.  It
can be replaced by `:=' or `='.

Conforming to
-------------

   `value' is an ISO-10206 Extended Pascal extension. `:=' in this
context is a VAX Pascal extension, and `=' is a Borland Delphi
extension.

Example
-------

See also
--------

   *Note var::, *Note type::, *Note Variable Declaration::, *Note Type
Declaration::.


File: gpc,  Node: var,  Next: view,  Prev: value,  Up: Reference

var
===

Synopsis
--------

   As part of a variable declaration part:
     var VARIABLE IDENTIFIER: TYPE IDENTIFIER;
   or
     var VARIABLE IDENTIFIER: TYPE DEFINITION;
   and with initializing value:
     var VARIABLE IDENTIFIER: TYPE IDENTIFIER value CONSTANT EXPRESSION;
   or
     var VARIABLE IDENTIFIER: TYPE DEFINITION value CONSTANT EXPRESSION;

As part of a parameter list:
     var VAR PARAMETER;
   or with type declaration
     var VAR PARAMETER: TYPE IDENTIFIER;

or with forced passing by reference:
     protected var VAR PARAMETER;
   or with type declaration
     protected var VAR PARAMETER: TYPE IDENTIFIER;

Description
-----------

   In a declaration part: The reserved word `var' declares a VARIABLE
IDENTIFIER whose type is of TYPE IDENTIFIER or which is defined by TYPE
DEFINITION.  For further description see *Note Variable Declaration::,
*Note Type Declaration::, *Note Type Definition::, *Note Data Types::.

   In a parameter list: see *Note Subroutine Parameter List
Declaration::.

Conforming to
-------------

   `var' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants. Untyped `var' parameters in parameter lists are
a UCSD Pascal extension.

Example
-------

     program VarDemo;
     
     type
       FooType = Integer;
     
     var
       Bar: FooType;
       ArrayFoo: array [0 .. 9] of Integer;   { array var definition }
       FecordFoo: record                      { record var definition }
                    bar : Integer
                  end;
       CharsetFoo: set of Char;               { set var }
       SubrangeFoo: -123 .. 456;              { subrange var }
       EnumeratedFoo: (Mon, Tue, Wed, Thu, Fri, Sat, Sun);  {enumerated var }
       PointerBar: ^FooType;                  { pointer var }
     
     procedure ReadFoo (var foo: FooType);
     begin
       ReadLn (foo)
     end;
     
     begin
     end.

See also
--------

   *Note type::, *Note array::, *Note record::, *Note set::, *Note
Subrange Types::, *Note Pointer::, *Note protected::.


File: gpc,  Node: view,  Next: virtual,  Prev: var,  Up: Reference

view
====

   Not yet implemented.

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: virtual,  Next: Void,  Prev: view,  Up: Reference

virtual
=======

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: Void,  Next: volatile,  Prev: virtual,  Up: Reference

Void
====

   (Under construction.)

Synopsis
--------

     type
       Void  { built-in type }

Description
-----------

Conforming to
-------------

Example
-------

     program VoidDemo;
     
     procedure p (var x : Void);
     begin
     end;
     
     var
       i: Integer;
       s: String (42);
     
     begin
       p (i);
       p (s)
     end.

See also
--------


File: gpc,  Node: volatile,  Next: while,  Prev: Void,  Up: Reference

volatile
========

   (Under construction.)

Synopsis
--------

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: while,  Next: with,  Prev: volatile,  Up: Reference

while
=====

Synopsis
--------

     while BOOLEAN EXPRESSION do
       STATEMENT

Description
-----------

   The `while' statement declares a loop. For further description see
*Note while Statement::.

Conforming to
-------------

   `while' is defined in ISO-7185 Standard Pascal and supported by all
known Pascal variants.

Example
-------

     program WhileDemo;
     var
       Foo, Bar: Integer;
     begin
       WriteLn ('Enter an descending series of integer numbers.');
       WriteLn ('Terminate by breaking this rule.');
       WriteLn ('Enter start number: ');
       Bar := MaxInt;
       ReadLn (Foo);
       while Foo < Bar do
         begin
           Bar := Foo;
           ReadLn (Foo)
         end;
       WriteLn ('The last number of your series was: ', Bar)
     end.

See also
--------

   *Note repeat Statement::, *Note for Statement::


File: gpc,  Node: with,  Next: Word,  Prev: while,  Up: Reference

with
====

   (Under construction.)

Synopsis
--------

Description
-----------

   _Note_: `with' statement overwrites program namespace.

Conforming to
-------------

Example
-------

   ...

   { Note bar is overwritten by foo.bar }  ...

See also
--------


File: gpc,  Node: Word,  Next: WordBool,  Prev: with,  Up: Reference

Word
====

Synopsis
--------

     type
       Word = Cardinal;
   or
     type
       Word (n) = Cardinal (n);

Description
-----------

   `Word' is the "natural" unsigned integer type in GNU Pascal.  On
most platforms it is 32 bits wide and thus has a range of
`0..4294967295'.  It is the same as *Note Cardinal::, introduced for
compatibility with other Pascal compilers.

   As an extension, GPC allows to use `Word' as a pseudo-schema to
produce types with a specified size in bits; for example

     type
       Word16 = Cardinal (16);

   defines an unsigned integer type with 16 bits.  The same mechanism
works for `Cardinal' and `Integer', too.

   `Word' in GNU Pascal is compatible to `unsigned int' in GNU C.

   There are lots of other integer types in GPC, see *Note Integer
Types::.

Conforming to
-------------

   ISO Pascal does not define `Cardinal'.  (However see *Note Subrange
Types::.)

   The `Word' type appears in Borland Pascal and Delphi, too, where it
is a 16-bit unsigned integer type.

Example
-------

     program WordDemo;
     var
       a: Word;
     begin
       a := 42;
       WriteLn (a)
     end.

See also
--------

   *Note Integer Types::, *Note Subrange Types::.


File: gpc,  Node: WordBool,  Next: Write,  Prev: Word,  Up: Reference

WordBool
========

   (Under construction.)

Synopsis
--------

     type
       WordBool = Boolean (BitSizeOf (Word));

Description
-----------

Conforming to
-------------

Example
-------

     program WordBoolDemo;
     var
       a: WordBool;
     begin
       Word (a) := 1;
       if a then WriteLn ('Ord (True) = 1')
     end.

See also
--------


File: gpc,  Node: Write,  Next: WriteLn,  Prev: WordBool,  Up: Reference

Write
=====

   (Under construction.)

Synopsis
--------

     procedure Write (var F: TYPED FILE; VARIABLE);
   or
     procedure Write (var F: Text; VALUES AND FORMAT SPECIFICATIONS);
   or
     procedure Write (VALUES AND FORMAT SPECIFICATIONS);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: WriteLn,  Next: WriteStr,  Prev: Write,  Up: Reference

WriteLn
=======

   (Under construction.)

Synopsis
--------

     procedure WriteLn (var F: Text; VALUES AND FORMAT SPECIFICATIONS);
   or
     procedure WriteLn (VALUES AND FORMAT SPECIFICATIONS);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: WriteStr,  Next: xor,  Prev: WriteLn,  Up: Reference

WriteStr
========

   (Under construction.)

Synopsis
--------

     procedure WriteStr (var Dest: String; VALUES AND FORMAT SPECIFICATIONS);

Description
-----------

Conforming to
-------------

Example
-------

See also
--------


File: gpc,  Node: xor,  Prev: WriteStr,  Up: Reference

xor
===

Synopsis
--------

     operator xor (operand1, operand2: Boolean) = Result: Boolean;
   or
     operator xor (operand1, operand2: INTEGER TYPE) = Result: INTEGER TYPE;
   or
     procedure xor (var operand1: INTEGER TYPE; operand2: INTEGER TYPE);

Description
-----------

   In GNU Pascal, `xor' has three built-in meanings:

  1. Logical "exclusive or" between two `Boolean'-type expressions.
     The result of the operation is of `Boolean' type.  (Logical `foo
     xor bar' in fact has the same effect as `foo <> bar'.)

  2. Bitwise "exclusive or" between two integer-type expressions.  The
     result is of the common integer type of both expressions.

  3. Use as a "procedure":  `operand1' is "xor"ed bitwise with
     `operand2'; the result is stored in `operand1'.


Conforming to
-------------

   ISO Pascal does not define the `xor' operator; Borland Pascal and
Delphi do.

   Use of `xor' as a "procedure" is a GNU extension.

Example
-------

     program XorDemo;
     var
       a, b, c: Integer;
     begin
       if (a = 0) xor (b = 0) then
         c := 1  { happens if either `a' or `b' is zero,    }
                 { but not if both are zero or both nonzero }
       else if a xor b = 0 then  { bitwise xor }
         c := 2  { happens if a = b }
       else
         xor (c, a)  { same as `c := c xor a' }
     end.

See also
--------

   *Note and::, *Note or::, *Note Operators::.


File: gpc,  Node: Keywords,  Next: Support,  Prev: Reference,  Up: Top

9 Pascal keywords and operators supported by GNU Pascal.
********************************************************

   This chapter lists all keywords understood by GNU Pascal.

   By default, keywords can be redefined to make it possible that every
correct ISO 7185 program can be compiled. However, you can use the
compiler dialect switches (e.g., `--extended-pascal' or
`--borland-pascal') to tell GPC that keywords of a given standard must
not be redefined.

   The keywords are taken from the following standards:

   * ISO 7185 Standard Pascal (SP)

   * ISO 10206 Extended Pascal (EP)

   * ANSI draft Object Pascal (OP)

   * USCD Pascal (USCD)

   * Borland Pascal 7.0 (BP)

   * Borland Delphi (BD)

   * Pascal-SC (PXSC, Pascal eXtensions for Scientific Calculations)

   * VAX Pascal (VP)

   * GNU Pascal extensions (GPC)

   In GPC you are free to re-define everything that is not a reserved
word in ISO 7185 Pascal in your program or the dialect selected.  E.g.,
you do not have to modify your code for GPC if you have an identifier
like `Restricted' or `Value' or some such, unless you compile with the
`--extended-pascal' option.

   The following table lists all known keywords with short
descriptions. The links point to the longer descriptions in the
reference.

absolute (BP, BD, GPC) (*note absolute::)
     overloaded variable declaration

abstract (OP, GPC) (*note abstract::)
     abstract object type declaration (not yet implemented)

all (GPC) (*note all::)
     `export' (*note export::) extension (`export foo = all')

and (any) (*note and::)
     Boolean or bitwise `and' operator or part of the `and then' (*note
     and then::) operator

and_then (EP, OP, GPC) (*note and_then::)
     short-circuit Boolean `and' (*note and::) operator

array (any) (*note array::)
     array type declaration

asm (BP, BD, GPC) (*note asm::)
     GNU style inline assembler code

asmname (GPC) (*note asmname::)
     linker name of routines and variables

attribute (GPC) (*note attribute::)
     attributes of routines and variables

begin (any) (*note begin::)
     begin of a code block, part of a `to begin do' (*note to begin
     do::) module constructor

bindable (EP, OP, GPC) (*note bindable::)
     external binding of files

case (any) (*note case::)
     multi-branch conditional statement or variant record type

class (OP, BD, GPC) (*note class::)
     OOE/Delphi style object classes (not yet implemented)

const (any) (*note const::)
     constant declaration or constant parameter declaration

constructor (OP, BP, BD, GPC) (*note constructor::)
     object constructor

destructor (OP, BP, BD, GPC) (*note destructor::)
     object destructor

div (any) (*note div::)
     integer or real division operator

do (any) (*note do::)
     part of a `while' (*note while::) or `for' (*note for::) loop, a
     `with' (*note with::) statement, or a `to begin do' (*note to
     begin do::) or `to end do' (*note to end do::) module constructor
     or destructor

downto (any) (*note downto::)
     part of a `for' (*note for::) loop when counting downwards

else (any) (*note else::)
     alternative part of an `if' (*note if::) statement, default case
     label or part of the `or else' (*note or else::) operator

end (any) (*note end::)
     end of a code block, end of a `case' (*note case::) statement, end
     of a record or object declaration, part of a `to end do' (*note to
     end do::) module destructor

export (EP, OP, BP, BD, GPC) (*note export::)
     module interface export

exports (BP, BD, GPC) (*note exports::)
     library export (not yet implemented)

external (EP, OP, UCSD, BP, BD, GPC) (*note external::)
     declaration of external objects

file (any) (*note file::)
     non-text file type declaration

for (any) (*note for::)
     loop statement where the number of loops is known in advance

forward (UCSD, BP, BD, GPC) (*note forward::)
     declaration of a routine whose definition follows below

function (any) (*note function::)
     function declaration

goto (any) (*note goto::)
     statement to jump to a `label' (*note label::)

if (any) (*note if::)
     conditional statement

import (EP, OP, GPC) (*note import::)
     module interface import

implementation (EP, OP, UCSD, BP, BD, GPC) (*note implementation::)
     module or unit implementation part

in (any) (*note in::)
     set membership test or part of a `for' (*note for::) loop when
     iterating through sets

inherited (OP, BP, BD, GPC) (*note inherited::)
     reference to methods of ancestor object types

inline (GPC) (*note inline::)
     declaration of inline routines

interface (EP, OP, UCSD, BP, BD, GPC) (*note interface::)
     module or unit interface part

interrupt (BP, BD) (*note interrupt::)
     interrupt handler declaration (not yet implemented)

is (OP, BD, GPC) (*note is::)
     object type membership test (not yet implemented)

label (any) (*note label::)
     label declaration for a `goto' (*note goto::) statement

library (BP, BD, GPC) (*note library::)
     library declaration (not yet implemented)

mod (any) (*note mod::)
     integer remainder operator

module (EP, OP, GPC) (*note module::)
     EP style or PXSC style (only partially implemented) modules

nil (any) (*note nil::)
     reserved value for unassigned pointers

not (any) (*note not::)
     Boolean or bitwise `not' operator

object (BP, BD, GPC) (*note object::)
     BP style object declaration

of (any) (*note of::)
     part of an array, set or typed file type declaration, a `case'
     (*note case::) statement, a variant record type or a `type of'
     (*note type of::) type inquiry

only (EP, OP, GPC) (*note only::)
     import specification

operator (PXSC, GPC) (*note operator::)
     operator declaration

or (any) (*note or::)
     Boolean or bitwise `or' operator or part of the `or else' (*note
     or else::) operator

or_else (EP, OP, GPC) (*note or_else::)
     short-circuit Boolean `or' (*note or::) operator

otherwise (EP, OP, GPC) (*note otherwise::)
     default case label

packed (any) (*note packed::)
     declaration of packed record or array types, also packed ordinal
     subranges

pow (EP, OP, GPC) (*note pow::)
     exponentiation operator with integer exponent

private (BP, BD, GPC) (*note private::)
     private object fields

procedure (any) (*note procedure::)
     procedure declaration

program (any) (*note program::)
     start of a Pascal program

property (OP, BD, GPC) (*note property::)
     variable properties (not yet implemented)

protected (EP, OP, BD, GPC) (*note protected::)
     read-only formal parameters and protected object fields

public (BP, BD, GPC) (*note public::)
     public object fields

published (BP, BD, GPC) (*note published::)
     published object fields

qualified (EP, OP, GPC) (*note qualified::)
     import specification

record (any) (*note record::)
     structured type declaration

repeat (any) (*note repeat::)
     loop statement

resident (BP, BD) (*note resident::)
     library export specification (not yet implemented)

restricted (EP, OP, GPC) (*note restricted::)
     type specification

segment (UCSD) (*note segment::)
     segment specification (not yet implemented)

set (any) (*note set::)
     set type declaration

shl (BP, BD, GPC) (*note shl::)
     bitwise left shift operator

shr (BP, BD, GPC) (*note shr::)
     bitwise right shift operator

static (GPC) (*note static::)
     static variable declaration

then (any) (*note then::)
     part of an `if' (*note if::) statement or part of the `and then'
     (*note and then::) operator

to (any) (*note to::)
     part of a `for' (*note for::) loop when counting upwards or a `to
     begin do' (*note to begin do::) or `to end do' (*note to end do::)
     module constructor or destructor

type (any) (*note type::)
     type declaration or part of a `type of' (*note type of::) type
     inquiry

unit (UCSD, BP, BD, GPC) (*note unit::)
     UCSD and BP style unit declaration

until (any) (*note until::)
     end of a `repeat' (*note repeat::) statement

uses (UCSD, BP, BD, GPC) (*note uses::)
     unit import

value (EP, OP, GPC) (*note value::)
     variable initializer

var (any) (*note var::)
     variable declaration or reference parameter declaration

view (OP, GPC) (*note view::)
     object class view (not yet implemented)

virtual (OP, BP, BD, GPC) (*note virtual::)
     virtual object method declaration

volatile (GPC) (*note volatile::)
     volatile variable declaration

while (any) (*note while::)
     loop statement

with (any) (*note with::)
     automatic record or object field access

xor (BP, BD, GPC) (*note xor::)
     Boolean or bitwise `exclusive or' operator


File: gpc,  Node: Support,  Next: To Do,  Prev: Keywords,  Up: Top

10 Where to get support for GNU Pascal; how to report bugs.
***********************************************************

   Here you can find information on where to find the most up-to-date
information about GPC, how you can get support (professional or
voluntary), how to use GPC's Test Suite, and how to report new bugs you
might encounter.

   If you have problems with GNU Pascal, please read the relevant
sections of the GPC Manual. The most current version of the manual is
available at
`http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc-doc.html' for
online browsing.  You can also download the complete manual in HTML
format (tar.gz) (`gpc-html.tar.gz' on GPC's WWW home page).  The manual
is also available in DVI format (gzipped) (`gpc.dvi.gz' on GPC's WWW
home page) and PostScript format (gzipped) (`gpc.ps.gz' on GPC's WWW
home page) for printing.

   If the manual doesn't help you, here is what we recommend you to do:

*Note FAQ::                Check the GPC FAQ

* Menu:

* Mailing List::           Join the GPC Mailing List
* Mailing List Archives::  Look in the Mailing List Archives
* Newsgroups::             Ask in a newsgroup
* Professional Support::   Get individual support for GPC
* Compiler Crashes::       If the compiler crashes...
* Reporting Bugs::         Find out how to report GPC bugs
* Testing::                If you have GPC sources, learn how to run
                           the Test Suite to test your bugs reported


File: gpc,  Node: Mailing List,  Next: Mailing List Archives,  Up: Support

10.1 The GPC Mailing List
=========================

   There is a mailing list devoted to GNU Pascal. You can write to the
mailing list, e.g. if you have problems installing GPC or if you found
a problem with GPC (please see *Note Reporting Bugs::). You can also
use it to discuss suggestions for improving GPC and, most welcome, to
offer your help or contribute code, documentation or other work. Mails
to the list should be in English.

   To subscribe to the mailing list, send the command
     subscribe gpc your@email.address
   in the body of a mail to <majordomo@gnu.de> (*not* to
`gpc@gnu.de'!). The subject is ignored. (Please replace
`your@email.address' with your real email address.) For more info, send
a line `help' to <majordomo@gnu.de>.

   You can send a message to the mailing list by sending email to the
list address <gpc@gnu.de> as if it were a person.

   To leave the mailing list, send the command
     unsubscribe gpc your@email.address
   to <majordomo@gnu.de>.

   There is also a (low-traffic) announce list, <gpc-announce@gnu.de>
that you can subscribe to stay up-to-date. To subscribe to the list,
write an email with
     subscribe gpc-announce your@email.address
   in the body to <majordomo@gnu.de>. If you like to announce a
contribution, a service or an event related to GPC, you are invited to
post to this list rather than `gpc@gnu.de', but please don't use the
announce list for questions or discussions. Please note that all mail
sent to the announce list is forwarded to the regular list, so you
won't have to subscribe to both lists if you don't want to miss
anything.


File: gpc,  Node: Mailing List Archives,  Next: Newsgroups,  Prev: Mailing List,  Up: Support

10.2 The GPC Mailing List Archives
==================================

   Perhaps your problem was already discussed on the list. There is a
searchable archive of the mailing list on the WWW. It can be browsed or
searched at `http://www.gnu.de/archive/wilma.cgi/gpc'.

   The archive of the GPC announcement list is at
`http://www.gnu.de/archive/wilma.cgi/gpc-announce'.

   _Note:_ Currently, the search option is working fine. If you find it
broken, please email me at <anja@drewitz.de>. Please don't mail a copy
to the GPC list because I let procmail move all mails with `To: gpc...'
and `Cc: gpc...' to a separate folder and would not see your mail for a
long time. -- Anja

   This archive starts in June 1999. For older messages, see:

     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/misc/gpc-list-1998.gz'
     (513 kB)
     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/misc/gpc-list-1997.gz'
     (995 kB)
     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/misc/gpc-list-1996.gz'
     (154 kB)
     `ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/misc/gpc-list-1995.gz'
     (42 kB)

   There is also a HTML version of these older archives at
`http://www.iula.upf.es/altres/pub/gpc/list2html/gpclist.htm'.


File: gpc,  Node: Newsgroups,  Next: Professional Support,  Prev: Mailing List Archives,  Up: Support

10.3 Newsgroups relevant to GPC
===============================

   To get support, you can also ask the Usenet newsgroups for help.
There are several Pascal related newsgroups, but none is dedicated just
to GNU Pascal, so use the one which is most appropriate for your
problem. For general Pascal questions, we recommend the following one:

`news://comp.lang.pascal.misc'       Pascal in general and ungrouped
                                     Pascals.

   Pascal syntax related questions may be appropriate in:

`news://comp.lang.pascal.ansi-iso'   Pascal according to ANSI and ISO
                                     standards.

   The next newsgroup is a haven for beginners, answering questions
that would apply to almost any Pascal. However, if you have a
GPC-specific question don't post there - use the GPC mailing list.  And
when in doubt use the GPC mailing list.

`news://comp.lang.pascal.borland'    Borland Pascal questions.

   Don't forget to give back what you have obtained. None of us is
getting money for answering your questions (unless you pay us by
yourself). Please do your part by answering the questions of others
instead.


File: gpc,  Node: Professional Support,  Next: Compiler Crashes,  Prev: Newsgroups,  Up: Support

10.4 Where to get individual support for GPC
============================================

   GPC is free software and comes *without any warranty*.

   If you want to get professional support, you can hire an individual
or a company for providing such a service.

   G-N-U GmbH (http://www.g-n-u.de) is doing large parts of the
development of GNU Pascal. This company offers special support for GPC
and can be contacted at <info@g-n-u.de>.

   More generally, to find a company or an individual who offers
support and other consulting services for free software, look into the
GNU Service Directory (http://www.gnu.org/prep/service.html).


File: gpc,  Node: Compiler Crashes,  Next: Reporting Bugs,  Prev: Professional Support,  Up: Support

10.5 If the compiler crashes...
===============================

   If the compiler crashes, you have discovered a bug. A reliable
compiler never crashes. To help the maintainers fix this bug, it is
important that you send us a problem report.

   If you're on Unix, you can find out where the compiler crashed if
you enable coredumps, then load the compiler (`gpc1') plus the core
file in the debugger (`gdb /your_path_here/gpc1 core'), then type
`backtrace' to get a stacktrace. Include this stacktrace in your bug
report.


File: gpc,  Node: Reporting Bugs,  Next: Testing,  Prev: Compiler Crashes,  Up: Support

10.6 How to report GPC bugs
===========================

   If you encounter a bug with GPC, please check whether it is one of
the known bugs (*note Known Bugs::). If not, please report it to the
GNU Pascal mailing list (*note Mailing List::). That way, they always
reach the maintainers. Please note the following points.

   * Please send a description of the problem. Try to give as much
     information as possible, with the full text of any error messages
     encountered, or a description of how some output varies from the
     expected output. Always specify the operating system type with
     version and the machine type (try `uname -a' if unsure) as well as
     the version of GPC as printed by `gpc -v'.

   * A good article on submitting bug reports can be found at either
     `http://www.chiark.greenend.org.uk/~sgtatham/bugs.html' or
     `http://freshmeat.net/news/2000/02/26/951627540.html'


   If the problem is with the compiler itself, not an installation
problem or something like this, please provide a test program to
reproduce the problem, and note the following hints. You can also
contribute test programs for features that are working in GPC to ensure
they will not break in future releases.

   * The test program should be as short as possible, but *by all
     means*, please send a *complete* program and *make sure* that it
     still reproduces the problem before you send it. Too often, users
     have sent code which contained obvious syntax errors far before
     the actual problem, or just code fragments we could only make wild
     guesses about. This is unproductive for us and doesn't help you
     get your problem solved.


   The preferred form for test programs is the form that the automated
GPC Test Suite understands. Please, if at all possible, send your test
programs in this form which should be easy to do, so we won't have to
waste our time to bring them into this form, and can concentrate on
fixing the problem.

   * The file containing the main program must contain the keyword
     `program' (case-insensitively) to be recognized by the testing
     script. Other files, which can contain units or modules or data
     needed by the program, must not contain the word `program'.

   * Since the Test Suite must run under very ... nah ... strange
     operating systems, too, file names must be distinguished in their
     first eight characters (case-insensitively) and should not contain
     anything but letters, numbers, hyphens, underscores and a single
     dot. The extension must be `.pas' to be recognized by the testing
     script. Furthermore, any ancillary files (units, modules,
     includes, data files) should not be longer than "8+3" characters.
     It is often a good idea to use your name, nickname or initials
     followed by a number as the file name.

   * The test program, when run, should produce a line of output
     consisting of the string `OK' (followed by a newline) if
     everything went as expected, and something else (e.g. `failed',
     possibly followed by the reason of failure) if something went
     wrong.

   * However, if the program is intended to check whether GPC catches an
     (intentional) error in the program, place the string `WRONG'
     somewhere in the test program, preferably in a comment in the line
     that contains the intentional error, and make the program output
     `failed' or something like this if it does compile mistakenly.


   The following special features of the testing script may be helpful
for constructing tests:

   * If the expected output is something else than `OK', place it in a
     file `<basename>.out' (where `<basename>' is the name of the test
     program without the `.pas' extension).

   * If the test program expects some input, place it in a file
     `<basename>.in'. It will automatically be redirected to the
     program's standard input.

   * If the test needs some special flags to be given to the GPC command
     line, place them in a comment preceded by `FLAG', e.g.:

          (* FLAG --extended-pascal -Werror *)

   * The source file name of the test program will be passed as the
     first command-line argument to the test program run.

   * If a test needs to be run in a special way, you can accompany the
     program with a script `<basename>.run' that will do the actual
     test after the test program was compiled. This script will be run
     by `sh' (regardless of its first line). In order to be portable,
     it should only use standard tools. The source file name of the test
     program will be passed as the first command-line argument to the
     run script in this case. The compiled file is always called
     `a.out'.

   * If a test needs to be compiled in a special way (e.g., to decide
     whether to skip the test), place the commands in a script
     (preferably called `<basename>.cmp'), and put the file name of the
     script (without directory) in a comment preceded by `COMPILE-CMD:'
     into the source of the test program. The compile script will be
     run *instead* of any other action for this test program, so it
     gives you maximum flexibility to do whatever you need to do. This
     script will be run by `sh' (regardless of its first line). In
     order to be portable, it should only use standard tools.  The
     first command-line argument to the compile script will be the
     compiler to use, including all options. The second argument will be
     the source file name of the test program. For some typical tests,
     there are standard compile scripts, e.g. `i386.cmp' which will
     skip the test unless run on an i386 compatible processor. This is
     necessary, e.g., when testing assembler code. Of course, it's still
     better to avoid having to use such scripts when possible.



File: gpc,  Node: Testing,  Prev: Reporting Bugs,  Up: Support

10.7 Running the GPC Test Suite
===============================

   _Note:_ If you have installed a GPC binary distribution, you usually
don't have the Test Suite installed (you can download the GPC source
distribution to get it, however), so this section does not apply to
you. Still, you can find in the section `Contributing Tests to the Test
Suite' how to report GPC bugs in the form of new test programs so we
can fix them as fast as possible.

   The files in the test directory and subdirectories are for testing
GPC only and should not be of any other use.

   Note: A few of the tests do not make sense on all systems. They are
equipped with checks and will be skipped if they find the system not
suitable. Skipped tests do *not* indicate a GPC bug, unless you have a
reason to be sure that the particular test should make sense on your
system.

   * To run the whole Test Suite, type `make' in the test directory (or
     `make check' in the `p' object directory after building GPC).

   * The output will show all errors encountered (hopefully none) and
     tests skipped, and finally display a summary giving the number of
     successful, failed and skipped tests. Any failed test indicates a
     bug in GPC which should be reported to the GPC mailing list,
     <gpc@gnu.de>. Don't forget to mention the operating system you ran
     the test on and any other relevant information about what you did.

   * You can also type `make pascal.check-long' to get a long output
     which is a sequence of file names followed by `OK' for successful
     tests, `SKIPPED' for skipped tests (both in capital letters), and
     anything else for failed tests.

   * To run only some of the tests, you can type something like `make
     MASK="foo[1-7]*.pas"' or `make MASK="foo42.pas" pascal.check-long'.

   * To clean up after running the tests, type `make clean'.



File: gpc,  Node: To Do,  Next: Internals,  Prev: Support,  Up: Top

11 The GNU Pascal To-Do List.
*****************************

   This is the To-Do list for the GNU Pascal Compiler.

   The GNU Pascal development team is constantly working on making GNU
Pascal more reliable and more comfortable. However, there are some
known bugs which will take some time to be fixed (any help welcome!),
and we do not want to hide them from you. You might also be interested
to know what features are planned to be implemented in the future. This
list is meant to keep track of the known bugs and wanted features of
GPC.

   If you want to report a new bug or suggest a new feature, the best
way to do it is in the mailing list. This way, other GPC users can
provide additional ideas, perhaps work-arounds for bugs, and the GPC
maintainers can sooner start to think about how to solve the problem.
The GPC mailing list is <gpc@gnu.de>. To subscribe, send the command
`subscribe gpc your@email.address' in the body of a mail to
<majordomo@gnu.de> (the subject is ignored). An archive of the mailing
list can be found on the GPC home page.

   The list changes every few days. The present version refers to the
current GPC snapshot, version 20001218.

   This list is part of the GNU Pascal Manual, included in GPC
distributions and snapshots. You can always browse the most current
version of the list on GPC's WWW page in HTML.  If you check the To-Do
list regularly you can decide if and when to try a new snapshort.

* Menu:

* Known Bugs::        Known bugs in GPC
* Planned Features::  Features planned for GPC
* Done::              Fixed bugs and implemented features


File: gpc,  Node: Known Bugs,  Next: Planned Features,  Up: To Do

11.1 Known bugs in GPC
======================

   In the following sections, you can find information about GPC bugs
that are known to the developers. The list always corresponds to the
latest developer versions of GPC, usually not to the latest official
distribution.

   If you encounter a bug with GPC, please check whether it is one of
the known bugs. If not, report it to the GNU Pascal mailing list.  (But
always report it if you solve the problem! ;-)

   Entries will be removed from the list as soon as the problem is
solved in the developers' current GPC version. (Exception: If we can't
reproduce the problem, but someone else can, the entry will be removed
when we hear from this person that the problem is solved.)  Problems
which are announced to be solved, but for which we (or the person who
can reproduce the problem) did not get the proof (i.e., a GPC source
patch) yet, are marked `(ok)'.

   A message ID (like `<42@foo.bar>') refers to a message in the GPC
mailing list where the topic was discussed (usually a bug report). A
note of the form `(xy20001231)' refers to an internal message of the
GPC developers. A file name like `(foo42.pas)' refers to the according
program in the GPC test suite included in the GPC source distribution.

* Menu:

* Urgent::  Things left to do until the next release of GPC
* Bugs::    Other known bugs in GPC


File: gpc,  Node: Urgent,  Next: Bugs,  Up: Known Bugs

11.1.1 Things left to do until the next release of GPC
------------------------------------------------------

   Bugs:

   * infinite compiler recursion when a unit uses itself (sven18.pas)
     <3A2275D8.F2DEA31A@zkm.de>

   * GPC crashes in the presence of old gpi files
     <3A2275D8.F2DEA31A@zkm.de>

   * the operators `pow', `**', etc. cannot be redefined (maur7.pas)

   * GPC crashes with invalid forward type declaration (nicola1.pas)

   * enumeration types declared within a set or record type or variable
     or constant declaration or the case selector of a record within a
     unit are not visible in the main program (fjf211.pas,
     fjf239[ab].pas)

   * enumeration types do not always properly survive transport through
     two interfaces (russell2.pas, miguel2.pas, daj2.pas)

   * some functions in boolean shortcuts are always called
     (fjf226[a-\infty].pas)

   * possible stack overflow when using string expressions in a loop
     (fjf419.pas)

   * GPC sometimes crashes with `-g'
     <Pine.SGI.4.10.9903231101500.6691-100000@pugh.bip.bham.ac.uk> (ok?)

   Wanted features:

   * make it possible to declare routines as I/O critical

   * `gp' make utility to replace automake; compile and link programs,
     but compile units without linking and without a warning that there
     is nothing to link; store GPC version numbers, platform and
     options in GPD files and re-compile automatically in `--automake'
     mode when they don't match; `--library-path' and `--include-path'
     as synonyms for (multiple) `-L' and `-I' options


File: gpc,  Node: Bugs,  Prev: Urgent,  Up: Known Bugs

11.1.2 Other known bugs in GPC
------------------------------

   * methods returning records don't work (chief39.pas)

   * bugs with packed subranges (couper[1-3].pas)

   * `setlimit' is applied when it shouldn't be ((a) variable/constant
     declarations, (b) `set of ShortCard', (c) constant sets), fatal
     range overflows in set constructors (couper8.pas, couper10.pas)
     <2C4F3FEF.20000809173117.FOO-13A6.frank@g-n-u.de>

   * string types declared in modules don't always work (daj3.pas)

   * declaring a procedure in the implementation with the same name as
     an imported procedure doesn't work (chief18.pas), detect name
     collisions between imported EP modules (mod9.pas)

   * don't allow assigning a pointer to a schema to a variable of type
     pointer to discriminated schema with different discriminant
     (fjf130.pas)

   * global dynamic variables (john1.pas) and global variables
     initialized by a function (fjf210b.pas) don't work

   * check for using, incrementing, ... unused variables
     <199711270257.VAA06393@mint.mint.net> (kevin2.pas), especially for
     strings, also for `for'-loop counters after the loop (EP 6.8.1)
     and modifying `for'-loop counters within the loop or in local
     routines <200005240807.EAA05355@mail.bcpl.net>

   * dynamic sets don't work (->PPS)

   * there are some bugs with mathematical functions. GPC fails, for
     example, the Paranoia test.

   * the compiler does not always recover well after a parse error
     <199911040915.KAA11168@humulus.daimi.au.dk>

   * type problem with const/protected integer parameters (chief31.pas)

   * bug with const parameters and derived object types (tc19991003)

   * give a warning rather than an error (and nothing in
     `--borland-pascal') when assigning/passing by value an object of
     derived type to one of a base type (and change the VMT pointer in
     the destination/actual parameter), don't change the VMT pointer
     when assigning to a polymorphic object (chief35[ab].pas,
     fjf451*.pas)

   * `prior parameter's size depends on `foo'' error with protected
     string parameters (daj1.pas)

   * declarations of subranges of enumeration types cause `conflicting
     types' messages (drf8.pas)

   * file parameters must not automatically be bindable in
     `--extended-pascal' (fjf193c.pas)

   * automatically close dynamically allocated files on dispose and
     files declared in a statement block at the end of the statement
     block (fjf219[a-c].pas); handle variant records correctly
     <6r9ir5$7v5$1@nntpd.lkg.dec.com> (fjf219d.pas); close files before
     gotos out of their scope (fjf219[ef].pas)

   * const real parameters don't work (fjf228.pas)

   * arithmetic expressions don't work as lower array/subrange bounds
     (fjf248.pas)

   * identifiers declared in a unit that have the same name as some
     object method are not visible (fjf278.pas, russell2.pas)

   * pointers to objects returned by methods can't be dereferenced
     (fjf299.pas)

   * integer parameters to built-in routines are not always converted
     to the right type (fjf349.pas)

   * types declared in a module interface are not visible in the
     implementation (kevin13.pas)

   * procedural variables are always passed by value
     <ABcLeYr887@e00827.vno.lt> (marius1.pas)

   * `inline' and `asmname' don't work together if compiling without
     optimization (maur3.pas)

   * module bug (mod12.pas)

   * Read, ReadStr and Val for all integer, real, char and string
     types; [no-]read-range-checking (also for subtypes of char!),
     [no-]read-base-specifier, [no-]read-white-space (not in Val!)
     (read?.pas)

   * fixed string comparisons are wrong (takashi1.pas)

   * char fields of packed records don't work in read (tom5.pas)

   * count of parameters to methods in error messages should not
     include Self
     <8F990E3D9A6FD1118F3B0000F81EA1D84985CE@exchsa2.dsto.defence.gov.au>

   * bug on machines with strict alignment requirements
     <199906021618.MAA06228@sten27.software.mitel.com>

   * too many parameters to `New' are not checked

   * `MedInt' (and therefore SizeType under DJGPP) is not accepted as
     the 4th parameter to BlockRead, BlockWrite (fjf252.pas)

   * compilation of interface declarations takes quadratic time

   * installation: bug(s) in GPC's makefiles; Make-lang.in is missing a
     rule so GPC can't be built without building GCC

   * forward referencing pointers generate debug info that appears as
     generic pointers; no information of `with' statements is currently
     given to the debugger; error in debug entries generated for
     objects
     <8F990E3D9A6FD1118F3B0000F81EA1D84985D7@exchsa2.dsto.defence.gov.au>

   * problems with initialising sets to the empty set
     <onOioOAQz365EwbY@tcs02.demon.co.uk>

   * Solaris: the preprocessor doesn't understand `defined'
     (fjf266.pas,fjf238.pas)
     <19990129132623.21658.qmail@euler.stams.strath.ac.uk>

   * HP/UX: `unrecognizable insn' error in connection with conformant
     or const string parameters)
     <199809280741.JAA17719@rug105.cs.rug.nl> (sietse1.pas),
     <Pine.SOL.4.10.9908051751550.23095-100000@niflheim.rutgers.edu>,
     <396C3531.3A327722@cs.rug.nl>


File: gpc,  Node: Planned Features,  Next: Done,  Prev: Known Bugs,  Up: To Do

11.2 Features planned for GPC
=============================

   In the following sections, you can find informations about features
which have been suggested and/or discussed for inclusion into GPC,
usually in the GPC mailing list. The division into the sections and the
names of the sections may change when this seems useful. The entries
within each section are in no particular order.

   Some of the entries may be a bit difficult to read. Double question
marks (`??') within the entries mean that it's not yet clear how to do
the thing. Triple question marks (`???') mean that it's not clear
whether to do it at all. ;-)

* Menu:

* Planned - Strings::            String types
* Planned - Records/arrays::     Record and array types
* Planned - Files::              Files
* Planned - Other types::        Other types
* Planned - Units and modules::  Units and modules
* Planned - OOP::                Object oriented programming extensions
* Planned - Misc::               Miscellaneous GPC topics
* Planned - Utilities::          Useful utilities for GPC


File: gpc,  Node: Planned - Strings,  Next: Planned - Records/arrays,  Up: Planned Features

11.2.1 Planned features: Strings
--------------------------------

   * const/var `AnyString' parameters and pointers (records internally,
     cf. gpc.pas) (GetCapacity; only for var parameters)

   * `SetLength' for non-Pascal string types; use truncate-flag; don't
     require extended syntax for `SetLength'

   * make work on all string types: string functions from
     rts/gstrings.pas, Concat/+ (function with conformant array;
     Optimize `s := s + ch') (fh19971105)

   * new option `--arrays-of-char-as-cstrings={none,zero-based,all}' to
     allow assigning [zero-based] arrays of char to cstring variables
     (warning otherwise) (cstrini2.pas); make padding of those arrays
     in initialized variables and in assignments dependent on this
     switch (fh19970921) (fjf57.pas, ok) and if the length matches
     exactly, give a warning (fh19971013) (cstrassign.pas); pass those
     arrays as cstrings in read*, write*, str (P_*STRING; current
     length=-1 in two places); compile time warning (and treatment as
     non-zero-based) if it's not clear at compile time if a conformant
     array or schema is zero-based or not, and an operation depends on
     this in the zero-based state

   * Short strings (Length, Capacity) and switches
     (tc19980326.2,tc19980327); allow `type x=string' (undiscriminated)
     when switch is set so that strings don't default to length 255
     (fh19971113) (fjf97.pas, ok); don't add a #0 terminator when
     passing as a CString parameter (automatically use String2CString)

   * automatically convert CStrings to Strings?

   * optimize assignment of and (non-trimming) comparison with a
     constant empty string

   * general switch `--bp-strings'

   * offer trimming string relations as functions

   * undiscriminated strings -> remove pointers to string constants

   * `WriteStr'-like function

   * unused local variables of string types are not detected

   * wide characters

   * open array/string parameters (`$P', `$V' in BP; undocumented
     `OpenString' identifier in BP)


File: gpc,  Node: Planned - Records/arrays,  Next: Planned - Files,  Prev: Planned - Strings,  Up: Planned Features

11.2.2 Planned features: Records/arrays
---------------------------------------

   * array/record initializers: recognize indices and field names
     (sven4.pas), ISO structured constants (constdef.pas); variant
     records <C1256791.0021F002.00@synln01.synstar.de>; allow omitting
     fields; fields in arbitrary order ???; index/field name optional;
     arrays: warning/error when too few fields are given; initialized
     schemata

   * initialized types in records/arrays (inirec[24].pas)

   * when applying `New' to a variant record type with a selector
     given, only allocate the space necessary for the selected variant
     (varrec2.pas)

   * Oregon and Vax Pascal structured constants
     <80256540.005E7D08.00@buffer1.quantel.com> ???

   * automatically detected upper array bounds in structured
     constants/intialized variables (-> PXSC)

   * simplify code generated to compute size of dynamical variables if
     no bitfields are involved

   * tagging feature for with statements (Sun Pascal) (tom6.pas)
     <200012022215.eB2MFD614424@wsinpa16.win.tue.nl>


File: gpc,  Node: Planned - Files,  Next: Planned - Other types,  Prev: Planned - Records/arrays,  Up: Planned Features

11.2.3 Planned features: Files
------------------------------

   * AnyFile parameters and pointers

   * keep files in FDRList while they live, not only while they're
     open, so _p_fdrdone() can be applied to all of them

   * packed files (EP) ??

   * write: left/center/both(?) justification???; rounding (PXSC) ???

   * BlockRead, BlockWrite: make last parameter internally a function
     result and allow any integer type to be passed for it for
     compatibility with 16 bit BP code

   * improve TFDDs (also for typed and untyped files)
     (OpenProc/CloseProc)

   * read/write operators ???

   * let Assign call _p_initfdr() in `--borland-pascal'


File: gpc,  Node: Planned - Other types,  Next: Planned - Units and modules,  Prev: Planned - Files,  Up: Planned Features

11.2.4 Planned features: Other types
------------------------------------

   * read Booleans and enum types from files, write enum types to files

   * UCSD Pascal's `Integer[n]' ??? BCD?

   * enum types with specified values ???; Inc, Pred, ... ??

   * enum type extensions (syntax??)

   * check for dereferencing nil pointers

   * general subtypes ???

   * type cast operators ???

   * make `SizeOf' work on specially declared untyped var and const
     parameters (`AnyType'?)

   * sparse sets; sets of arbitrary types ?? ???

   * optimize set constructors even better ???

   * superfluous warning with sets and variable elements (fh19970928)

   * variables of type undiscriminated schema; functions returning
     undiscriminated schemata (pg19980813.3)

   * record and array values (EP)

   * initalization and finalization code for arbitrary types (e.g. GMP
     types)

   * give an error rather than a warning when casting between types of
     different size in {$X-}

   * storage class qualifiers (`external', `asmname', `static',
     `volatile', `attribute')

   * `SELECTED_REAL_KIND' for real types (cf. Fortran, drf) ?? ???

   * resize schemata (cf. `SetLength' in Delphi)


File: gpc,  Node: Planned - Units and modules,  Next: Planned - OOP,  Prev: Planned - Other types,  Up: Planned Features

11.2.5 Planned features: Units and modules
------------------------------------------

   * qualified identifiers <34508F33.4F685BD1@keele.ac.uk> (also
     `program_name.identifier'?) (problem module.id vs. record.field);
     also for operators; `gpc' for built-in identifiers; duplicate
     identifiers in different units (fjf260[ab].pas); giving the same
     name to a routine in an interface and a local routine doesn't work
     (fjf240.pas); don't capitalize variable names in error messages
     and file name queries

   * `external name', `asmname', ...; (-> BP, Delphi) ??, like `$L'
     (fh19990325.2)

   * modules without implementation ??? (pmod1.pas)

   * `asmname' for units

   * `gpc-main' in GPI files

   * qualified import (mod10.pas)

   * units without initialization code or variables needing
     initialization should not get a constructor

   * GPI format ??

   * inline functions in GPI files

   * unit inheritance (of a complete interface with one statement or
     selectively)
     <Pine.HPP.3.96.971105161603.28577A-100000@tea.geophysik.tu-freiberg.de>,
     <199711061008.LAA25341@agnes.dida.physik.uni-essen.de> ??; virtual
     procedures ???

   * allow accessing non-exported identifiers in the implementation of
     a module ???
     <Pine.BSI.3.96.971110210330.7570A-100000@malasada.lava.net>

   * `Initialization/Finalization' (Delphi: =`to begin/end do') (???)
     (only in `--delphi'?)


File: gpc,  Node: Planned - OOP,  Next: Planned - Misc,  Prev: Planned - Units and modules,  Up: Planned Features

11.2.6 Planned features: OOP
----------------------------

   * init VMT (fjf445*.pas)

   * published, public, protected, private (scope limited to a unit in
     `--borland-pascal', and to the object type normally)

   * `ProcVar := Obj.Method' {$X+}

   * VMT link (global, local, new: set to 0 or @VMT; destructor: reset
     to 0)

   * checks: @object<>nil, typeof(object)<>0, size=-negsize; separate
     switches; function initialized (that does these 3 tests) ???

   * virtual constructors

   * `OBJ is CLASS', type cast

   * `is_exactly' (instead of `TypeOf (OBJ) = TypeOf (CLASS)' ???

   * `CLASS is CLASS' (implemented in Pascal with `Parent')

   * `OBJ is INTERFACE' (not so easy?) ???

   * abstract methods, object types

   * allow method-implementation right after the declaration ???

   * friends ???

   * `dynamic' (= `virtual' ?)

   * `class' (reference to an object type); allow classes and object
     types to inherit from each other; OOE;
     <01BD7A3A.6B187A20.prucha@helicon.co.at>; obpascal.zip

   * `New': Delphi syntax; Dispose?? (automatically?; set references
     automatically to nil) (-> FPC)

   * `--base-class=foo', `--base-object=bar' ???

   * properties <01BD7A3A.6B187A20.prucha@helicon.co.at>,
     <16131.199805071354@potter.cc.keele.ac.uk>

   * interfaces (cf. OOE, Java)

   * object constants???

   * virtual constructors in interfaces (load)???

   * VMT problem with interfaces (my solution??? also with dynamic
     linking???)

   * VMTs (also for local classes (EP modules???)!) in GPI files,
     written to assembler file by main program; `--cfiles=foo': .s file
     with VMTs for C/assembler??? (also .h???)

   * Variables of type pointer to more than one interface [and class]
     (also possible!)

   * method overloading ??? ??

   * class libraries (more or less TV compatible?/Free Vision/EFLIB)
     (streams as interface type?)

   * method pointers (`procedure/function of object') (-> Delphi) ???

   * declare VMT format in Pascal (only Size, NegSize, Parent,
     Childs?); <obj>.pVMT ?

   * VMT: ClassID (64/128 bits?) default 0, error when duplicated,
     warning when 0 and inherited from class with <>0 ?, not allowed
     for abstract classes!; ClassName (also for abstract classes?); [];
     ProgrammerID, BaseClassID at beginning of unit (redeclarable?) ???

   * in VMT: Parent: pVMT, Child: list of pVMT

   * for abstract classes: nearly empty VMTs (see VMT format)

   * find class by ClassID/ClassName (implementable in Pascal with
     `Child')

   * object constants, class variables (-> other name for `VMT');
     virtual/static

   * store in GPI: whether ClassID used, ClassName used, which classes
     are instantiated

   * `asmname' for methods


File: gpc,  Node: Planned - Misc,  Next: Planned - Utilities,  Prev: Planned - OOP,  Up: Planned Features

11.2.7 Planned features: Misc
-----------------------------

   * don't call procedures functions in error messages
     <200007230522.BAA05497@strawberry.ncifcrf.gov>

   * switch to warn about everything that could cause portability
     problems

   * document all compiler options and switches; make `gpc --help'
     output all the options ???

   * guarantee full evaluation in `{$B+}', `--borland-pascal mode'

   * libraries (static/shared; DLL)
     <Pine.HPP.3.96.971110183550.7996B-100000@tea.geophysik.tu-freiberg.de>

   * smart linking

   * range
     <Pine.LNX.4.21.0012091605570.8168-100000@rusty.russwhit.com>,
     overflow (right operand of mod <=0 is an error), nil pointer,
     string length, object VMT (pointer, negative size field), etc.
     checking <199911040915.KAA11168@humulus.daimi.au.dk>; also for
     array slice access (miklos1.pas); check that strings converted to
     CStrings don't contain #0 characters; initialize strings (length
     field), pointers, ordinal values and reals(?) with invalid values
     if checking is on

   * overloading of unary operators

   * warn about assigning the address of a local procedure (variable?)
     to a global pointer variable (fjf139.pas) or returning it from a
     function

   * intel assembler syntax; BP BASM ???

   * function overloading (in units and static methods?? - with
     different parameters, override or overload?); asmname?? (perhaps:
     first occurrence of a procedure with normal asmname (=> all
     non-overloaded procedures get normal asmnames)?); cf. Delphi
     methods without `override'

   * and_else, or_then (names??); guarantee complete evaluation in
     `{$B+}' mode

   * `?:' (`x := if c then bar else baz')

   * C operators (`,', `=', `++'/`--' (pre/post), `+=', ...), as
     functions ?

   * `for var : type = foo to bar do' ???

   * error/exception handling (Java,Delphi?)
     <01BD7A3A.6B187A20.prucha@helicon.co.at> (tc20000623)

   * RTS checking (libgpc_g), switch?

   * simplify math functions
     <199708091006.MAA26576@agnes.dida.physik.uni-essen.de>

   * variable number of arguments <32F9CFE7.5CB@lmemw.ericsson.se> ??
     ???

   * multithreading support ?? ???

   * `--wirth-pascal' :-)

   * PXSC standard... (pxsc.zip, /home/peter/pxsc) (??)

   * Object Oriented Extensions (Technical Report) (??)

   * generic types (cf. OOE section C.1) (gentypes.pas) ???

   * default parameters (cf. OOE section C.4; Delphi 4?)
     (iniparm[12].pas)

   * Pascal++ standard... (??) ???

   * allow `procedure foo; inline;'

   * compile time assertions ???

   * Ignore{Value,Result}/Discard and Swap for arbitrary types

   * make operators also available as functions

   * `absolute' with automatic type detection; `absolute' procedures
     (with automatic parameter detection) ???

   * Delphi features: Initialize, Finalize, Slice, TypeInfo ???,
     dynamic arrays (tc19991012)

   * output column numbers in error messages ??

   * get the address of a (direct or indirect) caller

   * warn when `and' and `or' are combined without parentheses
     (-Wparentheses; on by default)

   * store the casing of the first occurrence of a Pascal identifier
     for error messages etc.

   * assembler blocks should be considered volatile by default ???
     (fh19980829.4)

   * BP compatible `Graph' unit


File: gpc,  Node: Planned - Utilities,  Prev: Planned - Misc,  Up: Planned Features

11.2.8 Planned features: Utilities
----------------------------------

   * C header to Pascal translator

   * gdb: Pascal types (sets, files, subranges, schemata, strings, ...)

   * `indent'-like source code formatter for Pascal

   * AT&T <-> Intel assembler syntax converter ???


File: gpc,  Node: Done,  Prev: Planned Features,  Up: To Do

11.3 Fixed bugs and implemented features
========================================

* Menu:

* Fixed Bugs::            Problems that have been solved
* Implemented Features::  Features that have been implemented


File: gpc,  Node: Fixed Bugs,  Next: Implemented Features,  Up: Done

11.3.1 Problems that have been solved
-------------------------------------

   This section lists the bugs fixed since 1st Oct 1997, together with
the date (YYYYMMDD) on which they were fixed, so you can check if some
bug has already been solved in a recent release or developer version.

   After the release of GPC 2.1, this section will be cleared and
contain the bugs fixed after that release.

   * 20001206: DJGPP (and possibly other platforms): FileNameMatch (and
     related functions): patterns starting with `*' or `?' should not
     match file names starting with `.'

   * 20001118: Linux/Alpha: build-problems in rts/rta-va.c
     <14812.54955.265326.731526@gargle.gargle.HOWL>

   * 20001118: IRIX: writing reals doesn't work (gcc bug with varargs)
     <Pine.SGI.4.10.9903240952350.12280-300000@pugh.bip.bham.ac.uk>,
     <39DDC168.7CFFE872@larc.nasa.gov>

   * 20001107: bug with two-dimensional schema arrays (rudy1.pas)

   * 20001106: System: the return type of `MemAvail' and `MaxAvail'
     should be `Cardinal' rather than `Integer'

   * 20001025: FreeBSD: ``T_RESADFLT' undeclared' (fixed by removing
     IllReservedAddress, IllPriviledgedInstruction, IllReservedOp which
     are not very useful and may not have been supported on any system,
     anyway)

   * 20000902: if reading from files etc. is interrupted by signals,
     this causes an I/O error

   * 20000717: GMP unit: doesn't work with version 3.x of the GMP
     library

   * 20000626: slight errors in debug line number information for
     assignment or procedure call statements

   * 20000606: CRT doesn't work with windows > 255 chars wide or high

   * 20000529: the installation does not work without the `install'
     program installed <latimer@phg.mc.vanderbilt.edu>

   * 20000521: very hard reproducible bug(s?) (fjf212.pas; fh19980828.3)

   * 20000520: fatal signal 6 when trying to write a GPI file into a
     non-writable directory

   * 20000516: Dos: PackTime/UnpackTime give wrong results on
     big-endian machines

   * 20000505: `-I' options are forgotten after each include statement
     (ian4.pas)

   * 20000505: `div' also works as a real division (kevin14.pas)

   * 20000505: the arguments of long real functions are converted to a
     wrong type <9811112136.AA18086@sunflower.agron.iastate.edu>
     (robert1[ab].pas)

   * 20000505: problem with rewrite on file of packed array of packed
     record (daj7.pas) <48378@tcs01.demon.co.uk>

   * 20000505: `Extend'ing a file previously `Reset' without an
     intermediate `Close' doesn't work correctly (daj13.pas)
     <48469@tcs01.demon.co.uk>

   * 20000503: Sparc: division by reals (fjf237.pas, matt1.pas) or
     `Round (real_constant)' (chaput1.pas) make the compiler crash
     <199911040915.KAA11168@humulus.daimi.au.dk>

   * 20000503: division of complex numbers by reals doesn't work
     (maur4.pas)

   * 20000503: the Pascal main program does not get lineno stabs, so it
     is hard to debug it with GDB or RHIDE

   * 20000421: DosUnix: TranslateRedirections erroneously translates
     quoted redirections

   * 20000420: the compiler segfaults on `--uses=foo,bar'
     (fjf101[ab].pas)

   * 20000420: `--executable-file-name' doesn't work correctly with
     file names containing `\'

   * 20000420: DJGPP: `--automake' is more buggy than on other systems

   * 20000406: the preprocessor only understands C operators in `{$if}'
     directives, not Pascal operators like `not', `and', `or'
     (fjf423.pas)

   * 20000324: unit/module initialization and finalization code is
     executed in the wrong order (fjf185.pas)

   * 20000324: IRIX and AIX (and wherever else): unit/module
     initializers and finalizers are not executed

   * 20000323: Mingw: environment variables are not accessible

   * 20000319: ignore text after `$else' and `$endif', but warn if
     `--pedantic' was given (fjf412[ab].pas)

   * 20000319: character constants of the form #42 are not handled
     correctly in complicated macro usage (fjf205.pas)

   * 20000308: `attribute (const)' doesn't work

   * 20000226: during GPC build, the info files should be created in
     the source rather than the build directory, because they're
     included in source distributions

   * 20000221: global goto bug (goto4.pas, demos/parserdemo.pas)
     <3832137D.21C612FD@ujf-grenoble.fr>,
     <199911040324.WAA19382@kaylor.ncifcrf.gov>

   * 20000213: processing of initialized arrays takes quadratic time

   * 20000206: superfluous warning `cast increases required alignment
     of target type' (tmp) (fjf398.pas)

   * 20000202: `Close' should not be predefined in `--extended-pascal'
     <199912112311.SAA25109@mail.bcpl.net> (fjf393.pas)

   * 20000202: `case' in the main program doesn't work correctly (e.g.
     pretty.pas) (tmp)

   * 20000202: insufficient type checking with subranges (fjf305.pas)

   * 20000202: gpc-lex must not seek back (fjf311.pas; `-pipe' doesn't
     work correctly)

   * 20000202: Big-endian machines: some set operations don't work
     correctly (fjf329[ab].pas)

   * 20000202: gpc1 crashes when initializing a string with `ParamStr
     (1)'

   * 20000202: for a binary operation with a signed and an unsigned
     integer operand, use a signed type for the result (fjf325.pas,
     fjf326.pas)

   * 20000201: a few BP compatibility routines in the Dos and WinDos
     units (e.g. `GetDate') don't accept parameters of type Word if it
     was redefined using `-D__BP_TYPE_SIZES__'

   * 20000131: `--uses' doesn't work in units

   * 20000124: `gpc -B. -L. -v' should not try to link

   * 19991221: reference string parameters to RTS functions break after
     declaring a procedural variable with a value string parameter
     (fontana1.pas)

   * 19991107: CRT, CRTDemo: improved behaviour in response to screen
     size changes

   * 19990913: Sparc: `downto' loops with variables of size 1 bit don't
     work (fjf374.pas)

   * 19990905: GetCPUTime can't measure long CPU times reliably on some
     systems (e.g. Solaris)

   * 19990804: the variable `Environment' can be made invalid by PutEnv
     (e.g. on DJGPP), assignments to it are illegal (e.g. glibc), and
     some other problems with environment variables (fjf371.pas)

   * 19990802: GPM files are not stored in the unit-destination-path

   * 19990725: opened files can't be erased

   * 19990720: real constants of the form `0.5E+00' are not interpreted
     correctly (rick1.pas)

   * 19990712: function results of a string type declared in another
     unit are not correctly converted to CStrings (fjf302.pas)

   * 19990623: type error with schemata containing strings (fjf189.pas)

   * 19990623: integer shifts should not alter the sign (fjf84[ab].pas,
     fjf355{,a}.pas)

   * 19990622: computed constants that don't fit into a LongestInt
     don't work (fjf41.pas,fjf88.pas)

   * 19990619: routines with const parameters don't work in procedural
     parameters (chief26.pas)

   * 19990618: two-unit bugs (baby2.pas, sam12.pas, maur6.pas)

   * 19990618: the construct `^f_oo' is misinterpreted as a
     Borland-style char constant (fjf350.pas)

   * 19990618: conformant array bounds of enum types don't work
     <C1256784.0026BE34.00@synln01.synstar.de> (pd2.pas)

   * 19990618: enum variables cannot be used in a `for var in'
     statement <C1256784.0027179B.00@synln01.synstar.de> (pd1.pas)

   * 19990609: superfluous warning when `return'ing a char constant
     from a function returning a char (fjf249.pas,fjf351.pas)

   * 19990601: the Graph and CRT units cannot be used together
     (requires PDCurses update compiled with -DLIBBCC)

   * 19990512: Rewrite/Extend with a filename parameter don't check for
     the existence of the file (fjf348.pas)

   * 19990504: DJGPP: `FExpand'ing `x:' and `x:\..' can give strange
     results

   * 19990428: IOSelect doesn't work with the X11 version of CRT (fix
     includes PDCurses patch)

   * 19990412: bug with goto and local variables of non-constant size
     (berend3.pas) <004001be4bc2$24bfc9c0$0321a8c0@bmach.nederware.nl>

   * 19990411: EGCS: new errors (tom4.pas); new errors with `-g -O3'
     (forvars1.pas)

   * 19990411: EGCS: `New'ing a `File' pointer doesn't work
     (chief30.pas)

   * 19990410: missing range checking in `#42' char constants
     (fjf332.pas)

   * 19990403: Dos-like systems: Dos: FindFirst/FindNext file name
     matching should be case-insensitive
     <3705B550.B1AA360E@ujf-grenoble.fr>

   * 19990313: Solaris 2.7 (and perhaps other systems): FExpand doesn't
     work correctly with an empty directory name

   * 19990308: don't turn the lower index of an array slice access to 1
     (except for strings in `--extended-pascal') (fjf340[a-d].pas)

   * 19990304: BlockRead and BlockWrite don't check if the file is open
     for reading/writing (fjf339.pas)

   * 19990225: `Copy' and some other built-in routines don't check the
     number of arguments (fjf333.pas)

   * 19990223: DJGPP (and other systems without sinl() etc. in libm):
     long real Sin etc. produce linking errors
     <36D3063C.4D14F73C@cicc.unam.mx> (maur5.pas)

   * 19990222: `Null' is not accepted as an open or conformant array
     parameter

   * 19990219: `Break' and `Continue' with case statements are handled
     like in C, not like in BP <368563CE.F7F2D31C@mundivia.es>
     (fjf287[ab].pas)

   * 19990204: pointers to `file' don't work (chief28.pas)

   * 19990203: the order of objects/libraries in a `{$L}' directive is
     reversed

   * 19990203: cardinals are not converted correctly in some
     expressions (fjf324.pas)

   * 19990203: `Length' should return integer, not cardinal
     (fjf323.pas) (tmp)

   * 19990202: using undefined strings can cause segfaults at runtime
     (fjf322.pas)

   * 19990202: chars are not accepted as value/const string parameters
     to insert (fjf254.pas)

   * 19990202: DJGPP: CRT: ReadKey returns #10, not #13, for the enter
     key when CheckBreak is True

   * 19990201: FreeBSD: StatFS in the RTS doesn't compile
     <003001be4b65$1b0b2d50$0321a8c0@bmach.nederware.nl>

   * 19990130: ForceExtension doesn't handle empty wanted extensions or
     directory names with ExtSeparators in them

   * 19990129: RemoveDirSeparator erroneously removes the root
     directory slash

   * 19990129: CRT with ncurses: Read[ln] returns endless empty lines
     after the first line entered

   * 19990129: Bind should remove trailing DirSeparators from the file
     name (-> FSplit and some other functions don't work always/on all
     systems)

   * 19990128: Big-endian machines: CRT: the declaration of TWindowXY
     is wrong

   * 19990127: automake and autolink can't use units without source
     (fh19990124.2)

   * 19990127: let ExpandEnvironment, FileNameMatch and HasWildCards
     (formerly in GPCUtil, now in the RTS) handle `\' quotations
     (except under Dos systems, of course)

   * 19990126: Extend/Append can cause segfaults under more or less
     strange circumstances

   * 19990126: the (non-trimming) `>' and `<=' string operators are
     mixed up (chief27.pas)

   * 19990123: CRT: let CRT_Done be called before runtime errors so the
     error messages are not overwritten by closing curses

   * 19990122: reading from TTYs/pipes doesn't handle #0's correctly
     (fjf318[ab].pas)

   * 19990122: some superfluous warnings in `--borland-pascal' mode

   * 19990116: the compiler should abort if a C compilation fails
     (link8.pas)

   * 19990116: const parameters of schema type should be passed by
     reference, not by value (fjf315[ab].pas)

   * 19990115: problems treating `string' as `string(255)' in
     connection with procedural parameters (fjf241.pas)

   * 19990115: ignore `--executable-file-name', `--executable-path',
     `--unit-destination-path' etc. when `-S', `-c', ... is given

   * 19990112: Solaris (and other big-endian machines): writing chars
     doesn't work (fjf314.pas)

   * 19990110: DJGPP: when {$executable-file-name} is given, stubify
     doesn't get the correct file name, so no .exe is created

   * 19990109: linking errors with automake when a unit is not
     recompiled (fh19971015), <ABcLeYr887@e00827.vno.lt>
     (marius2[ab].pas)

   * 19990109: choose a unique temporary file name for the (former)
     .gpc files so that concurrent compilations don't conflict

   * 19990109: empty .gpc files before usage

   * 19990109: automake doesn't handle `uses' in implementation part of
     a unit (fjf200{,c}.pas)

   * 19990109: `$L' in units doesn't always work without `--autobuild'
     (link1[a-c].pas, link5[ab].pas)

   * 19990106: when compiling without automake and a needed unit is not
     found, compilation should abort immediately

   * 19990102: `$L' at the beginning of a source file makes the
     compiler crash (link6.pas)

   * 19981230: an integer subrange type is destroyed when a subrange of
     another type of the same size is being used as an array index
     (ross1.pas)

   * 19981230: arguments to `Dispose' are evaluated twice
     <36730596.81CC880C@mundivia.es> (miguel1.pas)

   * 19981230: the result of `Copy' can't be passed to `Val'
     (fjf306.pas) (tmp)

   * 19981228: fatal signal 6 when trying to write a GPI file into a
     non-writable directory

   * 19981227: autobuild doesn't recompile C files if the object file
     exists already

   * 19981227: passing a CString result of a function with parameters
     to a string parameters works, although it shouldn't, at least not
     without conversion (fjf242.pas)

   * 19981227: procedural variables should not be dereferenced when
     passed as an untyped parameter (fjf261.pas)

   * 19981227: integers can be passed for string parameters (fjf253.pas)

   * 19981227: for loops with counters of type subranges of char don't
     work correctly (chars2.pas) (tmp)

   * 19981220: missing type checking in `absolute' (fjf300.pas)

   * 19981219: don't pass Pascal specific options (e.g. `--automake')
     to gcc1, but do pass the other ones (fjf203.pas)

   * 19981217: `Polar' doesn't accept integer constants (fjf303.pas)

   * 19981212: DJGPP: fflush() clobbers the file position which causes
     some problems with GPC's file handling

   * 19981208: the preprocessor gets confused by two Pascal comments in
     sequence in an unusual situation
     <199812081112.LAA25879@stams.strath.ac.uk> (ian2.pas)

   * 19981207: set addition doesn't work correctly (ian1.pas)

   * 19981207: bug in set addition (fjf262.pas)

   * 19981207: some set operations don't work with optimization
     (fjf196.pas)

   * 19981207: comparing sets doesn't always work (chris5.pas)

   * 19981207: the automake mechanism doesn't always work properly to
     compile the Pascal parts of the RTS

   * 19981206: the result of built-in string functions can be passed as
     var (fjf298[a-\infty].pas)

   * 19981206: bugs on machines with strict alignment requirements
     (chris4.pas, confarr5.pas, pack{4,5,6,10,11,12}.pas)

   * 19981205: truncate strings in `Copy' (fjf40b.pas)

   * 19981205: CString2String doesn't work correctly with CStrings of
     length > 4 (fjf295.pas,fjf297[a-c].pas) (tmp)

   * 19981202: another instance of the two-unit problem
     (fjf294[ab].pas) (tmp)

   * 19981202: GCC2: typed constants don't work with `-g -O3'
     (fjf36.pas)

   * 19981202: don't allow files or structures containing files to be
     assigned via `:=' or returned from a function (john2[a-d].pas)

   * 19981202: only 1 parameter is accepted for C functions with
     varargs <3.0.6.32.19981110215411.007bb100@vegasnet.net> (ken1.pas)

   * 19981130: autobuild should recompile a unit only once, even if it
     is used from multiple places

   * 19981129: some invalid preprocessor directives cause infinite
     error messages (dollars.pas)

   * 19981129: storage class qualifiers don't work with typed constants
     and initialized variables (fjf245{,a}.pas)

   * 19981129: operator declarations with var parameters or const
     parameters of record type make the compiler crash (fjf232[a-c].pas)

   * 19981129: missing type checking with const parameters of record
     type (fjf231.pas)

   * 19981129: cyclic `uses' don't work (jesper5.pas)

   * 19981129: using a named subrange type as an array index spoils the
     range (sam11.pas)

   * 19981119: enum types with 128 or more elements don't work
     (sam9.pas)

   * 19981118: missing type checking with value string parameters
     (fjf291.pas)

   * 19981118: superfluous warning with constant sets and unsigned
     variables (fjf290.pas)

   * 19981118: missing type checking of method function results against
     string parameters (fjf289.pas)

   * 19981118: gpc segfaults after the declaration of `array [char] of
     boolean' (fjf288.pas)

   * 19981118: increase every object's alignment to the maximum in
     order to prevent alignment warnings with child types (fjf286.pas)

   * 19981118: schemata in variant records are not initialized
     correctly in some situations (fjf272.pas)

   * 19981118: another Low/High bug (fjf269.pas)

   * 19981118: another string parameter bug (cstrpar3.pas)

   * 19981118: gpc segfaults on `operator +;'

   * 19981116: subranges that occur in packed records can't be passed
     by reference <802566BB.0043115A.00@buffer1.HQ.quantel> (sam8.pas)

   * 19981116: val doesn't handle empty strings correctly (fjf292.pas)

   * 19981104: `--ignore-function-results' doesn't work with string
     return values (fjf282.pas)

   * 19981104: gpc1 segfaults on a strange schema usage (fjf275.pas)

   * 19981104: const void parameters don't work (fjf274.pas)

   * 19981104: external variables shouldn't be initialized again
     (fjf273.pas)

   * 19981104: missing type checking with High applied to arrays
     indexed by enumeration types (fjf271.pas)

   * 19981104: indexing an `array [false..true]...' doesn't work
     (fjf270.pas)

   * 19981104: don't initialize schemata and files when using GetMem as
     a procedure (baby.pas)

   * 19981020: string return values of object methods are not
     initialized (fjf281.pas) (tmp)

   * 19981020: severe bug with CString2String in a case statement
     (fjf279.pas)

   * 19980920: pass the correct specs to gcc1 (e.g. -D__i386__ on an
     x86) (predef.pas)

   * 19980918: `--executable-file-name' doesn't work with program names
     like `magic', `format', and prefixes of them (magic.pas)

   * 19980830: DJGPP: GPC crashes if the DJGPP variable is set
     incorrectly <ABfsDYraQI@e00827.vno.lt>

   * 19980830: DJGPP: `JDIR' problem

   * 19980830: make the To-Do list, __GPC_RELEASE__ and GPC archive
     file names y2k safe

   * 19980830: check conditions that are always true/false also for
     Cardinal (fjf225.pas)

   * 19980830: superfluous warning with ParamStr(ByteVar) (fjf224.pas)

   * 19980830: variables initialized by a function call don't work
     (fjf210.pas)

   * 19980830: the preprocessor can't handle `elif' (fjf236.pas)

   * 19980826: type checking bug with ^Longint (fjf223.pas)

   * 19980822: EGCS: new errors with `-g -O3' (objects.pas, retval.pas,
     testounit.pas)

   * 19980822: CString2String evaluates its argument mutiple times
     (fjf208.pas)

   * 19980822: give an error rather than a warning when
     passing/assigning incompatible pointer types (fjf201[a-h].pas)

   * 19980822: {$executable-file-name} doesn't work without `program
     foo' (results in a.out) (fjf51.pas)

   * 19980822: array ranges are not checked in schemata (schema4.pas)

   * 19980816: file buffers of files open for writing can't be read
     from (fjf220.pas) (tmp)

   * 19980802: extend/append should only work for text files in
     `--borland-pascal' (fjf202.pas)

   * 19980802: type casts into `file' don't work (fjf207.pas)

   * 19980729: define `__NEED_ALIGNMENT__' when needed

   * 19980729: incorrect cyclic `uses' are not recognized properly
     (fjf161.pas,fjf161u.pas,fjf162.pas)

   * 19980729: new does not work with an object pointer variable and
     constructor given (fjf155.pas)

   * 19980729: `_p_binding()' must only be called for files (fjf153.pas)

   * 19980729: fatal signal 6 when confusing a schema type witha schema
     variable (fjf151.pas)

   * 19980729: constant char arrays with boolean index range can't be
     declared like strings (fjf150.pas)

   * 19980729: multi-dimensional packed arrays are packed only in the
     outermost dimension (fjf149.pas)

   * 19980729: missing type checking of boolean array indices
     (fjf124a.pas)

   * 19980729: `virtual memory exceeded' with some sequences of
     automake options and an 8-char long program file name
     (fjf199aa.pas) (tmp)

   * 19980729: defining a type equals to text doesn't work in a unit
     (fjf198.pas)

   * 19980729: array slice access to CStrings doesn't work (fjf188.pas)

   * 19980729: gpc crashes when trying to pass a const string parameter
     to a value string parameter (fjf182.pas) (tmp)

   * 19980729: false warning when using `forward' in the implementation
     part of a unit (fjf177.pas)

   * 19980729: initialized variables in statement part don't work
     (fjf176.pas)

   * 19980729: initialized records with no fields given (`()') don't
     work (fjf175.pas)

   * 19980729: returning a string constant with `return' doesn't work
     (fjf174{,a}.pas)

   * 19980729: initialized string arrays, indexed with an enumeration
     type, don't work (fjf172.pas)

   * 19980729: initialized variables of simple (no record or array)
     schema types does not work (fjf171.pas)

   * 19980729: in some cases, a value type casting is done instead of a
     variable type casting for lvalues (fjf170.pas)

   * 19980729: problems treating `string' as `string(255)' in some
     cases (chief25a.pas)

   * 19980728: Bug with SeekWrite (russell1.pas)

   * 19980722: declaring an asmname for procedures in the
     implementation of a unit/module doesn't work

   * 19980722: schema, pointer and record types do not properly survive
     transport through two interfaces
     (fjf164.pas,orland1.pas,fjf178.pas)
     <Pine.3.89.9805202229.A26897-e400000@bc.seflin.org.>,
     <Pine.3.89.9805211812.B6540-9200000@bc.seflin.org.>

   * 19980722: DJGPP: Segfault while compiling a program which uses a
     unit with a long interface <3537FE98.A4417284@ujf-grenoble.fr>

   * 19980722: GPC's preprocessor outputs too many empty lines when
     removing text between {$ifdef} ... {$endif} (fh19971115),
     <ABcLeYr887@e00827.vno.lt>

   * 19980722: missing file mkstemp with GCC2

   * 19980722: set constants are not accepted for const set parameters
     (chief21.pas)

   * 19980722: With dynamic variables whose discriminant is initialized
     with a function call, the function is called twice (john1a.pas)

   * 19980722: set constants don't work in units (fjf195.pas)

   * 19980722: CString2String doesn't work on nil (fjf191{,b}.pas) (tmp)

   * 19980722: filename argument to reset is not handled properly
     (fjf186.pas,fjf187.pas)

   * 19980722: bug with string parameters (fjf184.pas) (tmp?)

   * 19980722: preprocessor bug with unterminated strings constants in
     undef-ed parts (fjf183.pas)

   * 19980722: High/Low don't work with schema-arrays and strings
     (fjf181{,a}.pas) (tmp)

   * 19980722: when assigning a string to a CString, no #0 is appended
     (fjf180.pas) (tmp)

   * 19980722: bug with converting big integer constants to reals
     (fjf179.pas) (tmp?)

   * 19980722: substrings of string constants give strange results
     (fjf168.pas)

   * 19980722: initialized strings with a #0 in them are cut after the
     #0 (fjf168.pas)

   * 19980722: operations should be promoted to the bigger operand's
     size (fjf167a.pas,fjf167b.pas)

   * 19980722: the last parameter of BlockRead and BlockWrite is not
     type checked (fjf163.pas)

   * 19980722: schema discriminants are not assigned in `New'
     (fjf152.pas)

   * 19980722: strings within a schema type are not recognized in
     read/write (fjf148.pas)

   * 19980722: exit doesn't work in main program in some situations
     (fjf147.pas)

   * 19980722: `--executable-file-name' has problems with 8+3 character
     long file names (fjf141aa.pas)

   * 19980722: strange error message at strange position
     (fh19980121:fjf140.pas)

   * 19980722: var parameters of type untyped file don't work
     (fjf138.pas)

   * 19980722: reset, rewrite, extend on untyped files should require a
     size parameter (except in `--borland-pascal'; there: default to
     128 and give a warning) (fjf136.pas,fjf137.pas)

   * 19980722: reset, rewrite, extend on untyped files don't allow a
     size parameter when given a file name, too (fjf126.pas)

   * 19980722: array with two dimensions, indexed by booleans, doesn't
     work (fjf124.pas)

   * 19980722: wrong comparison of byte with integer
     (fh19971130.2:fjf118.pas)

   * 19980722: don't allow `type y(b:integer)=array[1..b] of
     integer;x=y;' in `--extended-pascal' (fjf115a.pas)

   * 19980722: schema types that are no records or arrays
     (fh19971124:fjf114.pas,fjf114a.pas)

   * 19980722: don't allow writing strings to a file of char
     (fh19971130:fjf111.pas)

   * 19980722: constants can't be written to typed files (fjf110.pas)

   * 19980722: no constant range checking in FillChar (fh19971124)
     (fjf102.pas)

   * 19980722: ReadStr doesn't work with bit fields (fjf37a.pas) (tmp?)

   * 19980722: bug with constants and parameters of function type
     (knuth1a.pas)

   * 19980715: assigning string constant pointers to string pointer
     variables doesn't work (fjf194{,a,b,c}.pas)

   * 19980715: file variables should be automatically bindable without
     `--extended-pascal' (fjf193{,a,b}.pas)

   * 19980715: empty string constants don't work (fjf192.pas)

   * 19980715: superfluous warning when automatically adding the #0
     terminator to const strings (fjf190.pas)

   * 19980630: System: The declaration `Integer = Integer (16)' should
     come before `pInteger = ^Integer', and similarly for other
     declarations

   * 19980630: System: remove built-in procedures Seek and RunError

   * 19980629: an object type cannot be called `Time'
     <359458B1.9EC44A39@ujf-grenoble.fr>

   * 19980629: superfluous warnings `no previous prototype for
     __init_unitname' in Pascal parts of the RTS when making GPC

   * 19980629: gpc does not return an error status after a used unit
     does not exist (neither as source nor precompiled) or when
     auto-making a unit failed

   * 19980629: fixed size strings are not accepted for const string
     parameters (fixstr1.pas)

   * 19980629: superfluous warnings when initializing CStrings with a
     string constant and when assigning a string to a CString
     (fjf176.pas)

   * 19980611: writing to files via `filevar^' doesn't always work
     (fjf173.pas)

   * 19980531: allow resetting a file that was opened with rewrite,
     don't close it temporarily
     <199710081754.KAA17185@gnarly.swdc.stratus.com>

   * 19980523: EMX (dos?,os/2!): randomize doesn't work

   * 19980521: automake doesn't work on djgpp in gpc980401
     <352539F3.92DE9585@ujf-grenoble.fr>

   * 19980520: strings are passed to Insert and Delete by value rather
     than by reference after the declaration of a procedure with a
     value string parameter (fjf166.pas)

   * 19980520: name space conflict with strcmp and other functions
     (chief24.pas)

   * 19980520: System: set ExitProc to nil before calling

   * 19980520: System: remove built-in procedures fillchar, move,
     assign, paramcount, paramstr, insert, delete, pos, copy, str, val,
     int, frac, binfile stuff

   * 19980520: GPCTypes: type declarations (esp. string=bpstring)
     should rather be in system

   * 19980520: GPCTypes: use the modern integer type declarations;
     Integer,Word 16 bit;comp 64 bit with _Borland_16_Bit_

   * 19980520: Dos: include a dummy SwapVectors procedure

   * 19980512: don't pre-read the buffer in typed files after read
     (fjf104.pas)

   * 19980512: `Seek' and `SeekRead' etc. do not yet work in all
     situations (fjf95b.pas)

   * 19980416: non-text files opened with reset are not writable
     (fjf157.pas)

   * 19980416: position for writing into a file opened with reset is
     wrong by one record (fjf157.pas,fjf158.pas,fjf159.pas,fjf160.pas)

   * 19980410: `EOF' doesn't work with untyped files in djgpp
     (tc19980324)

   * 19980410: Dos line endings are not handled correctly in `ReadLn'

   * 19980405: reading chars from text files doesn't work (fjf131.pas)
     (tmp)

   * 19980405: `--borland-pascal': superfluous warnings `compiler
     directives ... incompatible' for `{$define}', `{$if[n]def}',
     `{$b+/-}', `{$x+/-}'

   * 19980405: make parameter to `GetFile' `const', not `var'

   * 19980405: read/write don't work with a text file as the only
     argument (fjf132.pas)

   * 19980405: randomized automake (fh19971015)

   * 19980405: chars are not accepted for const string parameters
     (chief22.pas)

   * 19980405: `xor' doesn't work with booleans (fjf154.pas)

   * 19980405: const parameters of undiscriminated schema type don't
     work (fjf144.pas)

   * 19980405: don't accept object methods that were not declared with
     the object type (fjf143.pas)

   * 19980405: GPC barfs on type checking with Boolean values in `case'
     statements <199801171504.QAA13384@agnes.dida.physik.uni-essen.de>

   * 19980405: Nested packed conformant arrays do not yet work in all
     cases <199801171504.QAA13384@agnes.dida.physik.uni-essen.de>

   * 19980405: Inside `New', all methods of an object become visible
     and may cause name clashes
     <199801171504.QAA13384@agnes.dida.physik.uni-essen.de>

   * 19980405: string value parameters don't work (fjf125.pas),
     <199802022303.SAA20015@mint.mint.net>

   * 19980405: pack and unpack don't work with conformant arrays

   * 19980405: checking of string var parameters is not strict enough
     (fh19971213:fjf123.pas)

   * 19980405: check for division by zero in constants at compile time
     (fh19971201:fjf121.pas)

   * 19980405: missing type checking of different integer types in var
     parameters (fh19971130:fjf109.pas)

   * 19980405: variable type casting of `^Integer' into `Pointer' for
     passing as var parameter doesn't work (fh19971130:fjf108.pas)

   * 19980405: GPC crashes when writing an array of char to a file of
     char <199711262349.SAA17009@mint.mint.net> (kevin3.pas)

   * 19980405: type casts of integer constants to `[Long]Real' don't
     work (fh19971124) (fjf113.pas)

   * 19980405: don't allow `Dec(Length(S), Count)' (fjf117.pas), `S[0]'
     (fjf116.pas) <199711181231.NAA14069@helena.mi.uni-erlangen.de>
     (2*fh19971124)

   * 19980405: produce an error instead of warning for constants out of
     range (fh19971124) (fjf103.pas)

   * 19980405: EMX: `Extend' doesn't work
     <199803090440.XAA08386@mint.mint.net>

   * 19980405: `Read[ln]': make INT_READ_HEX_MASK the default in
     `--borland-pascal'; `Write[ln]': REAL_CAPITAL_EXP_MASK
     (capexp.pas), make it the default in `--borland-pascal'

   * 19980401: fatal signal 11 with assignment to function method
     return value with a local type declaration (fjf142.pas)

   * 19980220: `ReadStr' causes an error when reading strings and
     source is empty

   * 19980215: `Seek' doesn't work with block devices

   * 19980215: `Seek' doesn't work with untyped files

   * 19980209: treat nil CStrings as empty in write

   * 19980120: `Overlay' is not a reserved word in BP

   * 19980113: bit fields don't work in read (bitfields.pas)

   * 19980112: `Int' and `Frac' don't work on constants
     <199801091201.HAA06756@mint.mint.net> (fjf74.pas) (tmp)

   * 19980106: when reading strings from text files, the capacity is
     too big by 1 (fjf133.pas)

   * 19971230: read doesn't work with packed arrays of char
     <199712300500.AAA30736@mint.mint.net>

   * 19971229: don't allow `4 .. 1'
     <199711270257.VAA06393@mint.mint.net> (subrw2.pas)

   * 19971229: too strict type checking with conformant arrays of char
     (confarr4.pas)

   * 19971229: too strict type checking in case statement with chars
     (chars2.pas)

   * 19971216: don't pre-read the buffer in files (fjf120.pas)
     <199712051906.UAA00483@agnes.dida.physik.uni-essen.de>

   * 19971215: use LongReal for long real constants (fh19971105)
     (fjf77.pas)

   * 19971215: file and string variables declared in the statement part
     are not initialized (fh19971130:fjf106.pas,fjf107.pas)

   * 19971215: too strict type checking with Seek (kevin4.pas)

   * 19971215: segfault with for loop in init code of a unit
     (bpcompat1.0:system.pas),(fh19971005) (maur1.pas)

   * 19971130: move whole words and take care of alignment when
     necessary in MoveLeft, MoveRight (moves2.pas) (moves3.pas)

   * 19971130: `Seek' to elements just written doesn't work
     (fh19971130:fjf110.pas) (tmp)

   * 19971130: remove `Bound_objects' and `Bound_free_list'
     <199710151621.SAA02929@helena.mi.uni-erlangen.de> (ciriaco1.pas)

   * 19971121: give a warning for `SizeOf (constant)'

   * 19971121: `sizeof(1+1)=4'; `sizeof(2)=8'; types of constants
     (fh19971113:fjf92.pas)

   * 19971121: LongInt constants for varargs parameters are passed as
     integers (fjf56.pas,fjf92.pas)

   * 19971121: sizes of [packed] subranges (fjf86.pas,fjf87.pas)

   * 19971121: detect integer constant overflows
     (fh19971113:fjf76.pas,fjf81.pas,fjf82.pas,fjf83.pas)

   * 19971121: make real numbers assignment compatible with complex
     numbers <97101711354779@petrella.cfilm.ba.cnr.it> (pg19971113)

   * 19971121: allow sizeof(discriminated schema type) (fjf99.pas);
     don't allow sizeof(undiscriminated schema type) (2*fh19971115)
     (fjf98.pas)

   * 19971121: `Seek' bug (2*fh19971113) (fh19971113)
     (fjf94.pas,fjf95.pas) (tmp); SeekRead bug (seekrd.pas)

   * 19971121: `array[boolean] of string(2000)' doesn't work
     (fh19971113) (fjf96.pas) (tmp)

   * 19971121: local inline functions after var declaration aren't
     parsed correctly (fh19971013) (fjf75.pas)

   * 19971121: `const procvar = proc' (fh19971113:fjf90.pas)

   * 19971121: check string var parameters for matching capacity
     (fh19971113:fjf91.pas)

   * 19971121: accept `else'/`otherwise' in a `case' statement without
     preceding `;' (fh19971112) (fjf80.pas)

   * 19971121: `else'/`otherwise' bug in `case' (multiple statements);
     don't allow a colon before it
     <199710061122.HAA26981@mint.mint.net>,
     <Pine.OSF.3.96.971007133527.1198C-100000@capella.hut.fi>

   * 19971121: wrong error messages for Insert (2*fh19971109)
     (fjf93.pas) (tmp)

   * 19971121: pointer addition: allow `+'/`-' and `Succ'/`Pred'; bug:
     adds n*Sqr(SizeOf(...)) instead of n*SizeOf(...)
     (fh19971113:fjf72.pas)

   * 19971121: don't allow reading of (non-typed) constants (error, not
     only warning) (fh19970928) (fjf45.pas)

   * 19971121: segfault with assembler code using a record component in
     a procedure (fh19971015) (fjf73.pas)

   * 19971121: wrong error message for invalid record components
     <199710152102.XAA04800@helena.mi.uni-erlangen.de> (fjf71.pas)

   * 19971116: accessing a packed array in a variant record does not
     work correctly
     <199711161700.SAA09857@agnes.dida.physik.uni-essen.de>

   * 19971116: capacity is not stored in a string in a variant record
     <199711161700.SAA09857@agnes.dida.physik.uni-essen.de>

   * 19971113: write blanks before `NaN' (pg19971113) (tmp)

   * 19971112: `Str' in `--borland-pascal': only a numeric argument
     (strbool.pas)

   * 19971112: bug with `goto' in a unit
     <3.0.2.32.19971005235702.006a032@icenet.com.au>

   * 19971112: array schema types of text files don't work (fh19971016)
     (fjf64.pas)

   * 19971112: don't allow schema object types (fh19971016) (fjf65.pas)

   * 19971112: don't allow the same identifier for schema type
     discriminator and a field of the schema (fh19971016) (fjf66.pas)

   * 19971112: fatal error with schema type referring to another schema
     type (fh19971016) (fjf67.pas)

   * 19971112: Pointers to string constants don't work (fh19971016)
     (fjf68.pas)

   * 19971112: bug with multidimensional conformant arrays
     <199710152102.XAA04800@helena.mi.uni-erlangen.de> (fjf69.pas)

   * 19971112: don't allow arrays with negative size (fh19970928)
     (fjf44.pas)

   * 19971112: `var procvar value proc': last program in
     <199707022313.BAA08656@helena.mi.uni-erlangen.de>,(fh19971003)

   * 19971112: segfault with `SqRt' in constant declaration in a unit
     (fh19971111) (fjf78.pas) (tmp)

   * 19971112: procedure in a unit accessing an array passed by
     reference segfaults (fh19971111) (fjf79.pas) (tmp)

   * 19971112: string overflows <6dRwLb2VlJB@rufus.central.de>
     <3258461722101997/A08869/HDC5/11BAB46E3A00*@MHS> (fjf40a.pas)
     (fh19971013)

   * 19971112: SubStr/Copy bug (fh19971013)

   * 19971112: sizes of [packed] subranges (fjf85.pas,fjf88.pas)

   * 19971111: bug with Rewrite,Reset with filename as second parameter
     <1948441422101997/A07437/HDC5/11BAB3AC2F00*@MHS>

   * 19971110: `prior parameter's size depends on ...' bug
     <80256546.003DB078.00@buffer1.quantel.com>

   * 19971110: unknown identifiers in module implementations
     <Pine.BSI.3.96.971108223417.5629A-100000@malasada.lava.net>

   * 19971106: string length check is off by 1 char (fh19971105)

   * 19971106: read and write without parameters are not accepted
     (fh19970928) (fjf43.pas)

   * 19971106: warn about assigning strings to chars (fh19971008)

   * 19971106: type checking in a case statement (fh19971008)
     (fjf58.pas)

   * 19971106: superfluous warning after reading in the return value of
     a function (fh19971003)

   * 19971106: `x absolute procvar': second to last program in
     <199707022313.BAA08656@helena.mi.uni-erlangen.de>,(fh19971003)
     (fjf48.pas)

   * 19971102: `Write (LongRealValue)' doesn't work with very big or
     small or unnormal numbers (2*fh19971105)

   * 19971101: problems with resetting an already open file
     <m0xIyyF-0006OkC@bockermann.ping.de>

   * 19971101: division of LongReals doesn't use full precision

   * 19971101: segfault with wrong program (undeclared array bound)
     (fh19971010)

   * 19971101: accept strings like `#48#49'
     <6dRwLb2VlJB@rufus.central.de>,
     <SIMEON.9710101739.A@muahost.cc.keele.ac.uk>,
     <199710102323.BAA15175@helena.mi.uni-erlangen.de>

   * 19971101: sometimes `*.gpc' files are not removed (fh19971015)

   * 19971101: give a warning for an assignment (or parameter passing)
     of a string to a char

   * 19971101: integer function result can't be assigned to a cardinal
     <199710282015.VAA17667@helena.mi.uni-erlangen.de> (kevin1.pas)

   * 19971022: uses in implementation part of a unit; circular unit
     references <7420001522101997/A07601/HDC5/11BAB3C01400*@MHS>

   * 19971013: `Dispose (nil)' causes a segfault (fjf63.pas)

   * 19971001: `type x=packed record a,b:packed 1..6 end': SizeOf (x) =
     8 (fjf31.pas) <199706271232.OAA15639@helena.mi.uni-erlangen.de>

   * 19971001: objects bug <SIMEON.9704041456.A@muahost.cc.keele.ac.uk>

   * 19971001: pointers to fields of packed arrays/records
     <199705010212.EAA29018@helena.mi.uni-erlangen.de> (3 items)
     (fjf55.pas)

   * 19971001: bug with redefined operator
     <6ZV6gbuMRMB@p-wendt.chateau.line.org> (chris1.pas)

   * 19971001: minor bug <199708111750.AA05985@hoover.gilbarco.com>
     (rphil5.pas)

   * 19971001: exported type bug
     <1.5.4.16.19970613155920.32b721e4@icenet.com.au>

   * 19971001: the set code generated in the Alpha causes runtime
     errors in the generated code

   * 19971001: put global variables into the data segment, not on the
     stack <199707261050.MAA21734@agnes.dida.physik.uni-essen.de>

   * 19971001: bug with call of sqr/abs/round/... in an expression as a
     parameter <6dNsBq9VlJB@rufus.central.de>

   * 19971001: GPC doesn't recognize equal types in connection with two
     units <2754032017091997/A08645/HDC5/11B98D033600*@MHS>


File: gpc,  Node: Implemented Features,  Prev: Fixed Bugs,  Up: Done

11.3.2 Features that have been implemented
------------------------------------------

   This section lists the new features implemented since 1st Nov 1997,
together with the date (YYYYMMDD) on which they were implemented.

   After the release of GPC 2.1, this section will be cleared, and the
features implemented after that release will either be listed in a new
section here or directly in the "news".

   * 20001216: CRT: new functions `AltGrKey', `ExtraKey'

   * 20001215: new function `GetTempFileNameInDirectory'

   * 20001210: new function `FormatTime', new constant `InvalidYear'

   * 20001206: new constant `MaskNoStdDir'

   * 20001205: the constant `MonthLength' was replaced by a function of
     the same name that handles leap years

   * 20001201: new constant `FileMode_Text_Reset_ReadWrite'

   * 20001115: `shl' and `shr' can also be used as procedures now

   * 20001112: new switches `-W[no-]object-directives'

   * 20001106: StringUtils: new routines `AppendStr', `StrCut',
     `Char2Boolean', `StrSkipSpaces', `StrReadQuoted',
     `StrReadDelimited', `StrReadWord', `StrReadConst', `StrReadComma',
     `StrReadInt', `StrReadReal', `StrReadBoolean', `StrReadEnum'

   * 20001017: DisposePPStrings

   * 20001016: `GetIOErrorMessage' now returns a string rather than a
     `CString'

   * 20001016: RegExType: changed the field `Error' from `CString' to
     `PString'

   * 20001016: GlobBuffer: replaced fields `Count' and `Result' by
     `Result' (`PPStrings')

   * 20001015: `GetOptErrorFlag' is now True by default

   * 20001014: StringUtils: new functions StrCount, StrReplace,
     Char2Digit, QuoteString, UnQuoteString, ExpandTabs,
     ExpandCEscapeSequences

   * 20001007: many new docdemo programs

   * 20001007: new options `-W[no-]underscore'

   * 20001003: many new docdemo programs

   * 20001001: many new `Reference' entries and new material in the
     `Programming' chapter in the manual

   * 20000917: added the `Size' field of BindingType again

   * 20000910: don't add a newline on `Extend' to text files that were
     bound as binary

   * 20000909: `GetOptLong' can now optionally derive the short options
     from the `LongOptions' array

   * 20000909: `CStringCharPos', `CStringLastCharPos': renamed to
     `CStringChPos' and `CStringLastChPos' to avoid confusion with
     `CharPos' and `LastCharPos'

   * 20000902: CRT: new procedure CRTSetTerminal

   * 20000828: new procedure FileMove

   * 20000826: new constant DayOfWeekName

   * 20000825: integrated the FAQ into the GPC Manual

   * 20000820: new routines SystemInfo, FileLock, FileUnlock, Alarm

   * 20000819: StringUtils: new unit, implementing a string hash table
     (further routines to be added)

   * 20000817: CRT: new routines CRTSavePreviousScreen,
     CRTSavePreviousScreenWorks

   * 20000806: new function GetTerminalName

   * 20000803: new functions UserID, GroupID

   * 20000723: new parameter `AccessTime' to SetFileName

   * 20000716: renamed the file mode constants from `fmFOO' to `fm_FOO'

   * 20000716: new routines MemoryMap, MemoryUnMap

   * 20000626: the default make target for testing GPC is called
     `pascal.check' (or `check-pascal') rather than `check-gpc' now;
     the test must be run in the build directory (not the `p'
     subdirectory) or in the `test' subdirectory of the source
     directory now

   * 20000619: `--borland-pascal': ignore everything after `end.' (also
     takes care of "^Z" characters at the end of Dos text files)

   * 20000613: Dos: special versions of GetCBreak and SetCBreak for
     MS-Windows

   * 20000612: Dos: new procedures (not only on DJGPP) DosVersion,
     SetDate, SetTime

   * 20000611: CRT: new procedures `SetScreenSize', `SetMonochrome';
     renamed `IsMonoMode' to `IsMonochrome'

   * 20000610: each of the parameters `Dir', `Name' and `Ext' to
     `FSplit' may now be null

   * 20000607: Single RTS command line options are now recognized with
     `--gpc-rts=OPTION' as well, and this can be given multiple times

   * 20000607: new procedure ResetGetOpt

   * 20000606: CRT: new functions CtrlKey, AltKey; new constants
     chCtrlA ... chCtrlZ, kbCtrlA ... kbCtrlZ

   * 20000605: new routines BlockSignal, SignalBlocked

   * 20000605: CRT with ncurses: changing the screen is now done
     through a shell command definable in the environment variable
     `RESIZETERM' (which defaults to `resize', `SVGATextMode' and
     `setfont'); the variables `crt_setfont_command_80_25',
     `crt_setfont_command_80_50', `crt_setfont_command_40_25' and
     `crt_setfont_command_40_50' (Linux only) were removed

   * 20000604: Dos: new procedures (not only on DJGPP) GetCBreak,
     SetCBreak, GetVerify, SetVerify

   * 20000604: new routines SetInputSignals, GetInputSignals

   * 20000531: new demo program `DynamicArrayDemo'

   * 20000530: integrated the interface of all units included with GPC
     into the GPC Manual; formatted the interfaces, also of gpc.pas,
     more nicely

   * 20000528: integrated the To-Do list and the list of new GPC
     features into the GPC Manual

   * 20000528: include the demo programs printed in the GPC Manual
     (currently 59, but expected to become more) into binary
     distributions in a directory `docdemos'

   * 20000527: restructured the GPC Manual

   * 20000526: in the GPC Manual, the list of command-line options and
     the list of keywords for the various dialects were updated, and
     from now on, they are automatically kept up to date, directly from
     the source

   * 20000526: changed the license of most units and the RTS from LGPL
     + exception to GPL + exception

   * 20000525: ReverseBytes, ConvertFromLittleEndian,
     ConvertFromBigEndian, ConvertToLittleEndian, ConvertToBigEndian:
     new parameter `ElementSize'; new demo program `EndianDemo'

   * 20000523: derive the keyword list in the documentation directly
     from the source

   * 20000521: WinCRT: new unit (identical to CRT)

   * 20000521: CRT: GetScreenSize renamed to ScreenSize (WinCRT
     compatibility); added some missing WinCRT compatibility stuff

   * 20000519: new function GetMountPoint

   * 20000516: new field Device in BindingType

   * 20000516: BlockReadLittleEndian, BlockReadBigEndian,
     BlockWriteLittleEndian, BlockWriteBigEndian: new parameter
     `ElementSize'

   * 20000516: new procedures ReadStringLittleEndian,
     ReadStringBigEndian, WriteStringLittleEndian, WriteStringBigEndian

   * 20000509: System: new functions Ofs, Seg, Ptr, CSeg, DSeg, SSeg,
     SPtr and a number of variables (mostly useless and only for BP
     compatibility)

   * 20000507: new procedure IOErrorFile

   * 20000505: `asmname' in variable and constant declarations must now
     come after the type; furthermore, `asmname' doesn't imply
     `external' anymore

   * 20000502: SeekEOF, SeekEOLn

   * 20000421: new function InstallSignalHandler

   * 20000418: recognize files with `.pp' or `.dpr' extension as Pascal
     sources

   * 20000415: new switch `{$[no-]debug-statement[=foo]}' (call a
     procedure automatically before each statement for debugging)

   * 20000415: RTS command line options are now recognized after
     `--gpc-rts' instead of `-Grts'

   * 20000415: removed `__cstring__', `__void__'

   * 20000414: the RTS command line options are now also available as
     long options; new RTS options `--version' (print RTS version and
     exit), `--abort-on-error' (abort with SIGABRT on runtime error),
     `--error-file', `--error-fd' (dump runtime error messages and
     strack trace to given file name or FD)

   * 20000412: runtime errors are now printed with their address to
     help debugging (using addr2line), and the address is stored in
     ErrorAddr

   * 20000411: new functions ReturnAddress, FrameAddress

   * 20000411: local compiler directives and defines with `{$local}'
     and `{$endlocal}' (fjf430*.pas)

   * 20000409: `{$ifopt}'

   * 20000409: case-[in]sensitve defines with {{$csdefine}} and
     {{$cidefine}} (or `-csdefine' and `cidefine'); `{$define}' (but
     not `--define') is now case-insensitive

   * 20000407: make `mod' with negative right operand work like in BP;
     allow expressions like `-2 * +3'

   * 20000407: `make check' now runs the current test suite rather than
     the (obsolete and removed) dejagnu tests; the test suite now
     produces a summary output by default, `make pascal.check-long' (or
     `check-pascal-long') produces the long output format as before

   * 20000407: new option `-W[no-]warnings' (enable/disable warnings)

   * 20000407: make single-letter compiler directives BP compatible
     (`--borland-pascal': ignore `$F', `$O' etc., ignore numbers after
     `$M'); new option `--[no-]stack-checking', also as compiler
     directives `{$[no-]stack-checking}' or `{$S+}'/`{$S-}'; new option
     `--[no-]typed-address', also as compiler directives
     `{$[no-]typed-address}' or `{$T+}'/`{$T-}'; replace
     `{$P+}'/`{$P-}' by `{$[no-]pedantic}' (or `--[no-]pedantic' on the
     command line); ignore `{W+}'/`{W-}' in `--borland-pascal' mode

   * 20000406: CRT: new variable CRTAutoInitProc; new procedure
     CRTNotInitialized

   * 20000405: new switches `--[no-]macros'

   * 20000402: new switches `-W[no-]field-name-problem'

   * 20000402: allow all `-Wfoo' options also as `{$W foo}' directives
     (no more `{$Wfoo}' like in the last alpha release!)

   * 20000331: replace `--no-nested-comments' by `--mixed-comments'
     (and vice versa); new options `--[no-]nested-comments',
     `-W[no-]mixed-comments', `-W[no-]nested-comments' (mixcom*.pas,
     nest*.pas); allow comments (but not compiler directives) within
     compiler directives

   * 20000331: make C style char escapes the default for strings
     enclosed in `""' (like `--char-escapes' used to do), and use `\"'
     rather than `""' to get a verbatim `"' in them; remove the
     `--[no-]char-escapes' switch and the `{$E[+-]}' compiler directive

   * 20000331: Delphi style `//' comments, new switch
     `--[no-]delphi-comments' and compiler option
     `{$[no-]delphi-comments}'

   * 20000327: new header gpc-in-c.h for inclusion of GPC code into C
     programs; new demo program GPC_C_Pas to demonstrate this

   * 20000327: allow `^const' to create a pointer to a constant

   * 20000327: don't expand macros in `--borland-pascal' and `--delphi'

   * 20000327: Dos: added the unportable Dos-only routines under DJGPP
     if `__BP_UNPORTABLE_ROUTINES__' is defined

   * 20000326: removed `__asmname__', `__const__', `__external__',
     `__inline__', `__static__', `__volatile__', `__byte__',
     `__short__', `__long__', `__longlong__', `__unsigned__'

   * 20000322: cleaned up the lexer; removed some fossils, e.g.
     `--c-numbers'

   * 20000306: file sizes can now be bigger than `Integer' (e.g. 64 bit
     files on 32 bit machines) if supported by the OS via lseek64() or
     llseek() (e.g. Linux, Solaris, IRIX)

   * 20000221: new types ByteBool, ShortBool, WordBool, MedBool,
     LongBool, LongestBool, Boolean(n) (fjf395.pas)

   * 20000219: build in Include, Exclude

   * 20000213: make `nil' also a value of any procedural/functional
     type (fjf258[a-e].pas)

   * 20000211: new functions `PathExists', `DataDirectoryName', new
     parameter `Prefix' to `ConfigFileName'

   * 20000211: new fields SymLink, TextBinary in BindingType; new
     procedure AssignBinary; removed variable TextFilesBinary

   * 20000202: new options `--[no-]progress-messages',
     `--[no-]progress-bar'

   * 20000202: ignore `{$L+}'/`{$L-}' directives (for BP compatibility)

   * 20000131: new unit MD5; new demo program MD5Demo

   * 20000124: new unit FileUtils; new demo program FindFilesDemo

   * 20000111: changed the internal file handling from using `FILE *'
     to integer file handles, to make it more efficient and get rid of
     some problems; replaced the `CFile' field in `BindingType' by a
     `Handle' field; replaced the `AssignCFile' procedure by an
     `AssignHandle' procedure; removed the `GetFile' function (note
     `FileHandle')

   * 20000111: new function Integer2String

   * 20000106: new functions IsPrintable, CharSet2RegEx

   * 19991217: System: new functions RealToBPReal, BPRealToReal

   * 19991217: new functions IsInfinity, IsNotANumber, SplitReal

   * 19991124: new demo program ProcVarDemo

   * 19991117: new function LongReal2Str to work-around the `Work
     (Real)' problem under IRIX

   * 19991110: CRT: DJGPP: added support for 40 column modes (requires
     updated PDCurses library)

   * 19991104: new demo program FExpandDemo

   * 19991103: CRT: changed the define to get an X11 version from
     XCURSES to X11

   * 19991102: added `Special' field to BindingType

   * 19991101: new function GetShellPath

   * 19991101: new option `--[no-]transparent-file-names' to derive the
     external file names from the file variable names
     <199909010105.VAA23844@kaylor.ncifcrf.gov> (fjf394.pas)

   * 19991025: CRT: new procedures SimulateBlockCursor,
     SimulateBlockCursorOff

   * 19991023: CRT: don't initialize curses at the beginning of the
     program, but initialize it automatically when the first CRT
     routine is called (for BP compatiblity); new procedure CRTInit to
     explicitly initialize CRT which also sets some defaults (PCCharSet
     and update level) to more natural (and less BP compatible) values

   * 19991023: CRT: allow any of the parameters to GetWindow to be null

   * 19991014: new procedure ReAlloc; previous ReAlloc function (libc)
     renamed to CReAlloc; new variable ReAllocPtr

   * 19991014: new functions GetPasswordEntryByName,
     GetPasswordEntryByUID, GetPasswordEntries; make ExpandEnvironment
     recognize `~user'

   * 19991006: RegEx: support for converting subexpression references
     to upper/lower case while replacing them with `\u7'/`\l7'

   * 19990924: new functions MemCompCase, StrEqualCase, PosCase,
     LastPosCase, PosFromCase, LastPosTillCase, IsPrefixCase,
     IsSuffixCase, ExecuteNoTerminal

   * 19990922: System: new procedure SetTextBuf for BP compatibility

   * 19990905: before building the RTS, make sure that the compiler
     version used is current, to prevent strange bugs when building
     with an older version <17698.990820@mg.dp.ua>

   * 19990805: new procedure SeedRandom; new variable SeedRandomPtr;
     automatically initialize the random number generator like
     Randomize does at the first call to Random unless SeedRandom was
     called before (only for the default RNG; not the BP compatible one
     in the System unit)

   * 19990802: new procedure RestoreTerminalClearCRT

   * 19990801: CRT: added support for panels (overlapping windows); new
     routines GetActivePanel, PanelNew, PanelDelete,
     PanelBindToBackground, PanelIsBoundToBackground, PanelActivate,
     PanelHide, PanelShow, PanelHidden, PanelTop, PanelBottom,
     PanelMoveAbove, PanelMoveBelow, PanelAbove, PanelBelow,
     IgnoreCursor

   * 19990728: new demo program ArraySliceDemo

   * 19990727: CRT: replaced the variables PCCharSet and
     UseControlChars by routines SetPCCharSet, GetPCCharSet,
     SetControlChars, GetControlChars

   * 19990727: GMP: new procedures mpf_exp, mpf_ln, mpf_pow,
     mpf_arctan, mpf_pi

   * 19990726: implemented environment variable management in Pascal,
     so that it's independent of libc differences (e.g. the presence or
     not of `environ'); new routines UnSetEnv, GetCEnvironment; removed
     PutEnv and CSystem functions (obsoleted by SetEnv and Execute);
     turned the Environment variable into a schema which contains the
     environment variables as CStrings; allow empty and case-sensitive
     environment variables within GPC programs even under Dos

   * 19990723: make `{$gnu-pascal}' completely equivalent to
     `--gnu-pascal'; add `{$gnu-pascal}' to all included units so they
     can also be compiled with `--automake' when `--foo-pascal' options
     are given (dialec[1-6].pas)

   * 19990723: new options `-W[no-]typed-const' and `-W[no-]near-far'

   * 19990720: new functions SetTerminalProcessGroup,
     GetTerminalProcessGroup

   * 19990719: new demo program RealPower

   * 19990709: new constants for signals; new routines Kill, WaitPID,
     SetProcessGroup (formerly in the Pipe unit)

   * 19990622: new function FileHandle; un-built-in GetFile - it is now
     in the GPC unit, but obsolete

   * 19990622: new routines AllocateBigMem, DisposeBigMem,
     MoveToBigMem, MoveFromBigMem, MapBigMem for uniform access to big
     memory blocks for GPC and BP; new demo program BigMemDemo

   * 19990617: integrated the PExecute unit into the RTS

   * 19990612: `register' directive

   * 19990609: integrated the GetOpt unit into the RTS (because the RTS
     uses it, anyway); removed the Internal unit from the installation
     (because using it from programs is really not recommendable)

   * 19990603: new procedure SetEnv (makes obsolete libc's PutEnv)

   * 19990601: included a `GPC' unit for BP to provide some GPC
     compatibility to BP programs

   * 19990527: new demo program TrapDemo

   * 19990527: new units HeapMon, Trap

   * 19990527: new function ReleaseCount

   * 19990526: new routines RegisterRestoreTerminal,
     UnregisterRestoreTerminal, RestoreTerminal

   * 19990502: new routine SetProcessGroup

   * 19990424: new function RegExPosFrom

   * 19990403: new constant FileNamesCaseSensitive, new function
     FileNameLoCase

   * 19990327: added 20 demo programs

   * 19990325: new function GetMicroSecondTime

   * 19990324: renamed the CString routines in the RTS so they get a
     `CString' prefix, moved the BP compatibility identifiers for the
     same routines into the `Strings' unit

   * 19990308: `--no-default-paths'

   * 19990307: new functions IOSelect, IOSelectRead

   * 19990225: `--no-{unit,object}-path'

   * 19990225: `--[no-]io-checking' and `{$[no-]io-checking}' as
     synonyms for `{$I+-}'

   * 19990219: recognize (but currently ignore)
     published/public/protected/private

   * 19990218: renamed DataReady to CanRead

   * 19990213: change warnings of the form `Foo-Pascal does not have
     foobars' into `foobars are {GPC-specific|a GPC extension}' and add
     spaces before all but the first line of multi-line messages

   * 19990211: new procedures Sleep, SleepMicroSeconds, GetCPUTime

   * 19990211: CRT: new procedures CRTUpdate, CRTRedraw, SetScroll,
     CRTSetCursesMode

   * 19990209: renamed the __BP_INTEGERS__ (System unit) and
     _Borland_16_Bit_ (Dos and WinDos units) defines to
     __BP_TYPE_SIZES__

   * 19990209: Pipe: new parameter `Process' to Pipe; new functions
     WaitPipeProcess, StrSignal, Kill, WaitPID; new constants (actually
     variables) for the signals

   * 19990205: new routines HasWildCardsOrBraces, BraceExpand,
     MultiFileNameMatch, GlobOn, MultiGlob, MultiGlobOn, QuoteFileName,
     UnQuoteFileName, FExpandQuoted, ForceAddDirSeparator,
     FindNonQuotedChar, FindNonQuotedStr, NameExtFromPath; new
     parameter `Quoted' to RelativePath

   * 19990202: new declarations DirRoot, QuotingCharacter, EnvVarChars,
     EnvVarCharsFirst, WildCardChars, FileNameSpecialChars,
     ShellExecCommand

   * 19990127: new functions IsUpCase, IsLoCase, IsAlphaNum,
     IsAlphaNumUnderscore

   * 19990127: CRT: catch some signals and return pseudo function keys
     for them if CheckBreak is False

   * 19990125: added `User', `Group', `Mode' and `INode' fields to
     BindingType; new procedure ChMod

   * 19990125: CRT: react to screen size changes by external events and
     return a pseudo function key

   * 19990115: built in `null' (= `nil^')

   * 19990115: Pipe unit (also for Dos!)

   * 19990115: new function DataReady to check if data can be read from
     a file without blocking

   * 19990110: integrated the `PExecute' unit into GPC

   * 19990102: pass all given options to automake compilations too
     (without having to repeat them with `--automake="foo"'), remove
     `--automake="foo"'

   * 19990101: `--[no-]autolink' (default is autolink)

   * 19981228: `--[no-]executable-path',
     `--[no-]unit-destination-path', `--[no-]object-destination-path'

   * 19981222: implemented buffering to speed up reading from files

   * 19981213: integrated the following units into GPC: `GetOpt',
     `RegEx', `GMP', `Ports'

   * 19981212: new string routines: SetString, StringOfChar (Delphi
     compatibility)

   * 19981212: integrated the `DosUnix' unit into GPC

   * 19981210: integrated the `GPCUtil' unit into GPC

   * 19981208: integrated the following units into GPC: `System',
     `Turbo3'

   * 19981208: remove {$W-} as much as possible in the units

   * 19981208: built in Addr, Assigned

   * 19981207: integrated the following units into GPC: `CRT', `Dos',
     `Overlay', `Printer', `Strings', `WinDos'

   * 19981206: `--unit-path' (upath.pas), `--object-path' (opath.pas);
     don't allow them in a source file

   * 19981206: allow `Copy' with 2 arguments (fjf40e.pas)

   * 19981205: `FileName' function with a Pascal string return value

   * 19981205: interpret `{$L foo}' as `-lfoo'; accept files with `.so'
     extension in `{$L}'

   * 19981203: pre-define `__OS_DOS__' on Dos-like systems

   * 19981202: `--uses=foo(bar.pas),bar,baz(../baz.pas)' (fjf101b.pas)

   * 19981202: make `=' and so on for strings work as exact comparisons
     (`--borland-pascal'; `--[no-]exact-compare-strings')
     (fjf38{,[a-f]}.pas)

   * 19981201: pre-define __BORLAND_PASCAL__ etc. depending on the
     dialect options and __GNU_PASCAL__ if no dialect option was given
     (dialdef{,[1-6]}.pas)

   * 19981108: new time routines UnixTimeToTimeStamp and
     TimeStampToUnixTime

   * 19981108: added `AccessTime', `ModificationTime' and `ChangeTime'
     fields to BindingType

   * 19981021: added a `Force' field to BindingType

   * 19980921: procedures to convert the endianness of single variables
     (ReverseBytes, Convert{From,To}{Little,Big}Endian) and to do this
     while reading/writing them from/to untyped files
     (Block{Read,Write}{Little,Big}Endian)

   * 19980919: MaxLongInt

   * 19980918: a number of new CString routines, including almost all
     (that weren't already there) of BP's strings unit

   * 19980918: WinDos: portable BP compatible unit with most of the
     routines (those that can possibly be implemented in a portable way)

   * 19980917: CRT: some win (TP 5), wincrt and tpcrt compatibility
     routines and some extensions added

   * 19980915: Internal: unit, with the internal RTS declarations from
     gpc.pas moved into it

   * 19980914: System: remove built-in procedures UpCase, LoCase,
     ChDir, MkDir, RmDir, FileSize, AddNullTerminator, InOutRes,
     IOResult, FileMode

   * 19980914: System: GetDir, Lo, Hi, Swap, MemAvail, MaxAvail,
     HeapError, HeapErrorNilReturn

   * 19980912: declared CGetMem, CFreeMem, ReAlloc

   * 19980909: build in GetMemPtr, FreeMemPtr

   * 19980830: allow `RunError' without arguments (error code -1)

   * 19980830: `--no-automake', `--no-autobuild', `--no-autolink' (each
     of them disables all of `--autolink', `--automake' and
     `--autobuild')

   * 19980822: internally remove the `type' parameter to _p_bind()

   * 19980818: build in GPC_StatFS

   * 19980724: procedures UpCaseString, LoCaseString, functions
     UpCaseStr, LoCaseStr

   * 19980722: longest{int,real}-field-width (fieldw.pas)

   * 19980722: allow collecting options in several `--automake' oder
     `--autobuild' options

   * 19980719: build in ExitCode, ErrorAddr

   * 19980719: Dos: portable BP compatible unit with most of the
     routines (those that can possibly be implemented in a portable way)

   * 19980717: added a `DayOfWeek' field to TimeStamp and a DayOfWeek
     function

   * 19980715: define __GPC_RELEASE__

   * 19980702: new CString functions: StrLen, StrEnd, StrScan,
     StrRScan, StrDup, StrCmp, StrCaseCmp

   * 19980701: new file name declarations and routines: PathSeparator,
     DirSeparator, DirSeparators, ExtSeparator, DirSelf, DirParent,
     NullDevice, TTYDevice, ConsoleDevice, GetCurrentDirectory,
     GetTempDirectory, GetTempFileName, GetTempFileName_CString,
     Slash2OSDirSeparator, OSDirSeparator2Slash,
     Slash2OSDirSeparator_CString, OSDirSeparator2Slash_CString,
     FileExists, DirectoryExists, FSearch, FSearch_Executable,
     Expand_Environment, FExpand, FSplit, DirFromPath, NameFromPath,
     ExtFromPath, OpenDir, ReadDir, CloseDir

   * 19980629: runtime I/O error handling with {$I+-}

   * 19980629: build in NewCString, StrPCopy, CString2String
     (fjf156.pas); String2CString

   * 19980629: build in UpCase, LoCase (locale-dependent, except in
     `--borland-pascal', there only 7 bit ASCII)
     (fjf165a.pas,fjf165b.pas)

   * 19980629: build in High, Low (for ordinal types and arrays)

   * 19980629: build in Random (for LongestCard and LongestReal),
     Randomize

   * 19980629: build in SizeType, PtrDiffType

   * 19980629: build in Pi
     <Pine.SGI.3.96.980318113542.2662B-100000@pugh.bip.bham.ac.uk>

   * 19980629: build in Erase, Rename, ChDir, MkDir, RmDir, FileMode,
     Flush

   * 19980628: internally remove the unused second parameter of
     Dispose/FreeMem

   * 19980626: allow mixing of New/GetMem/Dispose/FreeMem with
     malloc()/free() and with Mark/Release (except free() with Release
     in some cases)

   * 19980623: Turbo3 unit

   * 19980619: Printer: portable (piping to lpr under Un*x)

   * 19980613: `--gnu-pascal'

   * 19980611: CRT: portable ncurses-based unit

   * 19980604: print error messsages in the form: `a.out: [internal
     error:] unknown code in `Write' (error #904)'

   * 19980531: when opening a file with a file name, do a binding
     actually (fjf169.pas)

   * 19980523: added a `MicroSecond' field to TimeStamp

   * 19980520: printer unit for Dos

   * 19980520: `--uses="foo"' (fjf101.pas,fjf101a.pas)

   * 19980511: build in FilePos, FileSize, Truncate, Append

   * 19980511: build in RunError

   * 19980405: accept (but currently ignore) {$ifopt}

   * 19980405: When passing a long string value to a PChar parameter,
     automatically add a #0 terminator

   * 19980405: allow `type y(b:integer)=array[1..b] of integer; x=y;'
     (fjf115.pas)

   * 19980405: Fail (FreeMem, when constructor called by New)

   * 19980405: rename AssignLength and AssignType to SetLength and
     SetType, resp., for Delphi compatibility

   * 19980405: warn about absolute declarations and type casts that can
     cause alignment problems

   * 19980405: `--autobuild'

   * 19980129: predefine symbols for endianness

   * 19980114: recognize `--[no-]truncate-strings' in WriteStr
     (fjf59.pas,truncstr.pas)

   * 19980114: build in untyped files and BlockRead, BlockWrite
     (blockop.pas)

   * 19971230: build in Int, Frac (fjf129.pas)

   * 19971215: build in PtrInt, PtrCard, PtrWord

   * 19971130: allow opening files to `''' or `'-'' for stdin/stdout

   * 19971121: different versions of math functions for LongReal

   * 19971121: allow `with' for schema types
     <199710152102.XAA04800@helena.mi.uni-erlangen.de> (fjf70.pas)

   * 19971121: allow `(var) := expr' (fjf100.pas)

   * 19971112: build in ParamCount, ParamStr (params.pas)

   * 19971112: initialize arrays of text in a loop rather than
     individually (fh19971016) (fjf64.pas)

   * 19971112: build in Seek

   * 19971112: build in FillChar, Move (moving whole words), MoveLeft,
     MoveRight (moving single bytes) (moves.pas)

   * 19971106: build in Delete (fjf62.pas) (fh19971008), Pos
     (delinspos.pas), Copy

   * 19971106: AssignLength (alength.pas)

   * 19971101: make the char array in a String `[1..Capacity+1]' so
     that there's always space for a #0 terminator

   * 19971101: build in Str and Val; Str in `--borland-pascal': only
     one argument

   * 19971101: build in StdErr

   * 19971101: optimize `in' with set constructors

   * 19971101: build in Insert (fjf61.pas)


File: gpc,  Node: Internals,  Next: Contributors,  Prev: To Do,  Up: Top

12 The GPC Source Reference
***************************

     "The Source will be with you. Always."

   This chapter describes internals of GPC. It is meant for GPC
developers and those who want to become devlopers, or just want to know
more about how the compiler works. It does not contain information
needed when using GPC to compile programs.

   This chapter tells you how to look up additional information about
the GNU Pascal compiler from its source code.

   *Note:* If you intend to modify GPC's source, please check the top
of each file you're going to modify. A number of files are generated
automatically by various tools. The top of these files will tell you by
which tool and from what file they were generated.  Modifying a
generated file is pointless, since it will be overwritten the next time
the tool is run. Instead, modify the original source (which will often
be easier, anyway, e.g. a bison input file vs. the generated C code).
This also holds for various documentation files.

   Proprietary compilers often come with a lot of technical information
about the internals of the compiler. This is necessary because their
vendors want to avoid to distribute the source of the compiler - which
is always the most definitive source of this technical information.

   With GNU compilers, on the other hand, you are free to get the
source code, look how your compiler works internally, customize it for
your own needs, and to re-distribute it in modified or unmodified form.
You may even take money for this redistribution.  (For details, see the
GNU General Public License, *Note Copying::.)

   The following subsections are your guide to the GNU Pascal source
code. If you have further questions, be welcome to ask them at the GNU
Pascal mailing list (see *Note Support::).

   All file paths mentioned in this chapter are relative to the GNU
Pascal source directory, usually a subdirectory `p' of the GCC source.

* Menu:

* Lexical analyzer::     `gpc-lex.c' -- How GPC reads your source.
* Language definition::  `parse.y' -- ``Syntax diagrams'' as ``Bison'' source.
* Tree nodes::           `../tree.*' -- How GPC stores your program internally.
* Parameter passing::    `gpc-typeck.c' -- How GPC passes parameters.
* GPI files::            `module.c' -- How GPC's precompiled Module/Unit interfaces work.
* AutoMake::             `module.c' -- How GPC automatically ``makes'' a large project.
* File Layout::          Files that make up GPC; Integrating GNU Pascal in GCC

   (Under construction.)

   For more information, see chapters "Portability" through "Fragments"
in *Note the GCC documentation: (gcc)Top.


File: gpc,  Node: Lexical analyzer,  Next: Language definition,  Up: Internals

12.1 GPC's Lexical Analyzer
===========================

   The source file `gpc-lex.c' contains the so-called _lexical
analyzer_ of the GNU Pascal compiler.  (For those of you who know
`flex':  This file was _not_ created using `flex' but is maintained
manually.)  This very-first stage of the compiler (after the
preprocessor which is a separate executable) is responsible for reading
what you have written and dividing it into _tokens_, the "atoms" of
each computer language.  The source `gpc-lex.c' essentially contains
one large function, `yylex()'.

   Here is, for example, where the real number `3.14' and the subrange
`3..14' are distinguished, and where Borland-style character constants
like `#13' and `^M' are recognized.  This is not always a trivial task,
for example look at the following type declaration:

     type
       X = ^Y;
       Y = packed array [^A .. ^B] of Char;
       Z = ^A .. ^Z;

   If you wish to know how GPC distinguishes the pointer forward
declaration `^Y' and the subrange `^A..^Z', see `gpc-lex.c', function
`yylex()', `case '^':' in the big `switch' statement.

   There are several situation where GPC's lexical analzyer becomes
context-sensitive.  One is described above, another example is the token
`protected', a reserved word in ISO-10206 Extended Pascal, but an
ordinary identifier in ISO-7185 Standard Pascal.  It appears in
parameter lists

     procedure foo (protected bar: Integer);

   and says that the parameter `bar' must not be changed inside the
body of the procedure.

   OTOH, if you write a valid ISO-7185 Standard Pascal program, you can
declare a parameter `protected':

     procedure foo (protected, bar: Integer);

   Here both standards contradict each other.  GPC solves this problem
by checking explicitly for "protected" in the lexical analyzer:  If a
comma or a colon follows, this is an ordinary identifier, otherwise
it's a reserved word.  Having this, GPC even understands

     procedure foo (protected protected: Integer);

   without losing the special meaning of `protected' as a reserved word.

   The responsible code is in `gpc-lex.c' - look out for `PROTECTED'.

   If you ever encouter a bug with the lexical analyzer - now you know
where to hunt for it.


File: gpc,  Node: Language definition,  Next: Tree nodes,  Prev: Lexical analyzer,  Up: Internals

12.2 Language Definition: GPC's Parser
======================================

   The file `parse.y' contains the "bison" source code of GNU Pascal's
parser.  This stage of the compilation analyzes and checks the syntax of
your Pascal program, and it generates an intermediate,
language-independent code which is then passed to the GNU back-end.

   The _bison_ language essentially is a machine-readable form of the
Backus-Naur Form, the symbolic notation of grammars of computer
languages.  "Syntax diagrams" are a graphical variant of the
Backus-Naur Form.

   For details about the "bison" language, see *Note bison: (the Bison
manual)the Bison documentation.  A short overview how to pick up some
information you might need for programming follows.

   Suppose you have forgotten how a variable is declared in Pascal.
After some searching in `parse.y' you have found the following:

     /* variable declaration part */
     
     variable_declaration_part:
         LEX_VAR variable_declaration_list semi
       | LEX_VAR semi
           { error ("missing variable declaration"); }
       ;
     
     variable_declaration_list:
         variable_declaration
       | variable_declaration_list semi variable_declaration
           { yyerrok; }
       | error
       | variable_declaration_list error variable_declaration
           {
             error ("missing semicolon");
             yyerrok;
           }
       | variable_declaration_list semi error
       ;

   Translated into English, this means: "The variable declaration part
consists of the reserved word (lexical token) `var' followed by a
`variable declaration list' and a semicolon.  A semicolon immediately
following `var' is an error.  A `variable declaration list' in turn
consists of one or more `variable declarations', separated by
semicolons." (The latter explanation requires that you understand the
recursive nature of the definition of `variable_declaration_list'.)

   Now we can go on and search for `variable_declaration'.

     variable_declaration:
         id_list
           {
             [...]
           }
         enable_caret ':' optional_qualifier_list type_denoter
           {
             [...]
           }
         absolute_or_value_specification
           {
             [...]
           }
       ;

   (The `[...]' are placeholders for some C statements which aren't
important for understanding GPC's grammar.)

   From this you can look up that a variable declaration in GNU Pascal
consists of an "id list", followed by "enable_caret" (whatever that
means), a colon, an "optional qualifier list", a "type denoter", and an
"absolute or value specification".  Some of these parts are easy to
understand, the others you can look up from `parse.y'.  Remember that
the reserved word `var' precedes all this, and a semicolon follows all
this.

   Now you know the procedure how to get the exact grammar of the GNU
Pascal language from the source.

   The C statements, not shown above, are in some sense the most
important part of the bison source, because they are responsible for
the generation of the intermediate code of the GNU Pascal front-end,
the so-called _tree nodes_.  For instance, the C code in "type denoter"
juggles a while with variables of the type `tree', and finally returns
(assigns to `$$') a so-called _tree list_ which contains the information
about the type.  The "variable declaration" gets this tree list (as the
argument `$6') and passes the type information to the C function
`declare_vars()' (declared in `util.c').  This function
`declare_vars()' does the real work of compiling a variable declaration.

   This, the parser, is the place where it becomes Pascal.


File: gpc,  Node: Tree nodes,  Next: Parameter passing,  Prev: Language definition,  Up: Internals

12.3 Tree Nodes
===============

   If you want really to understand how the GNU Pascal language
front-end works internally and perhaps want to improve the compiler, it
is important that you understand GPC's internal data structures.

   The data structure used by the language front-end to hold all
information about your Pascal program are the so-called "tree nodes".
(Well, it needn't be Pascal source - tree nodes are language
independent.)  The tree nodes are kind of objects, connected to each
other via pointers.  Since the GNU compiler is written in C and was
created at a time where nobody really thought about object-orientated
programming languages yet, a lot of effort has been taken to create
these "objects" in C.

   Here is an extract from the "object hierarchy".  Omissions are marked
with "..."; nodes in parentheses are "abstract":  They are never
instantiated and aren't really defined.  They only appear here to
clarify the structure of the tree node hierarchy.  The complete list is
in `../tree.def'; additional information can be found in `../tree.h'.

     (tree_node)
     |
     |--- error_mark  (* enables GPC to continue after first error *)
     |
     |--- (identifier)
     |    |
     |    |--- identifier_node
     |    |
     |    \--- op_identifier
     |
     |--- tree_list  (* general-purpose "container object" *)
     |
     |--- tree_vec
     |
     |--- block
     |
     |--- (type)  (* information about types *)
     |    |
     |    |--- void_type
     |    |
     |    |--- integer_type
     |   ...
     |    |
     |    |--- record_type
     |    |
     |    |--- function_type
     |    |
     |    \--- lang_type  (* for language-specific extensions *)
     |
     |--- integer_cst  (* an integer constant *)
     |
     |--- real_cst
     |
     |--- string_cst
     |
     |--- complex_cst
     |
     |--- (declaration)
     |    |
     |    |--- function_decl
     |   ...
     |    |
     |    |--- type_decl
     |    |
     |    \--- var_decl
     |
     |--- (reference)
     |    |
     |    |--- component_ref
     |   ...
     |    |
     |    \--- array_ref
     |
     |--- constructor
     |
     \--- (expression)
          |
          |--- modify_expr  (* assignment *)
          |
          |--- plus_expr  (* addition *)
         ...
          |
          |--- call_expr  (* procedure/function call *)
          |
          |--- goto_expr
          |
          \--- loop_expr  (* for all loops *)

   Most of these tree nodes - struct variables in fact - contain
pointers to other tree nodes.  A `tree_list' for instance has a
`tree_value' and a `tree_purpose' slot which can contain arbitrary
data; a third pointer `tree_chain' points to the next `tree_list' node
and thus allows us to create linked lists of tree nodes.

   One example:  When GPC reads the list of identifiers in a variable
declaration

     var
       foo, bar, baz : Integer;

   the parser creates a chain of `tree_list's whose `tree_value's hold
`identifier_node's for the identifiers `foo', `bar', and `baz'.  The
function `declare_vars()' (declared in `util.c') gets this tree list as
a parameter, does some magic, and finally passes a chain of `var_decl'
nodes to the back-end.

   The `var_decl' nodes in turn have a pointer `tree_type' which holds
a `_type' node - an `integer_type' node in the example above.  Having
this, GPC can do type-checking when a variable is referenced.

   For another example, let's look at the following statement:

     baz := foo + bar;

   Here the parser creates a `modify_expr' tree node.  This node has two
pointers, `tree_operand[0]' which holds a representation of `baz', a
`var_decl' node, and `tree_operand[1]' which holds a representation of
the sum `foo + bar'.  The sum in turn is represented as a `plus_expr'
tree node whose `tree_operand[0]' is the `var_decl' node `foo', and
whose `tree_operand[1]' is the `var_decl' node `bar'.  Passing this
(the `modify_expr' node) to the back-end results in assembler code for
the assignment.

   If you want to have a closer look at these tree nodes, write a line
`(*$debug-tree="Foobar"*)' into your program with `FooBar' being some
identifier in your program.  (Note the capitalization of the first
character in the internal representation.)  This tells GPC to output the
`identifier_local_value' tree node - the meaning of this identifier -
to the standard error device in human-readable form.

   While hacking and debugging GPC, you will also wish to have a look
at these tree nodes in other cases.  Use the `debug_tree()' function to
do so.  (In fact `(*$debug-tree="Foobar"*)' does nothing else than to
`debug_tree()' the `identifier_local_value' of the `Foobar' identifier
node.)


File: gpc,  Node: Parameter passing,  Next: GPI files,  Prev: Tree nodes,  Up: Internals

12.4 Parameter Passing
======================

   GPC supports a lot of funny things in parameter lists:  `protected'
and `const' parameters, strings with specified or unspecified length,
conformant arrays, objects as `var' parameters, etc.  All this requires
sophisticated type-checking; the responsible function is
`convert_arguments()' in the source file `gpc-typeck.c'.  Every detail
can be looked up from there.

   Some short notes about the most interesting cases follow.

*Conformant arrays:*
     First, the array bounds are passed (an even number of parameters
     of an ordinal type), then the address of the array itself.

*Procedural parameters:*
     These need special care because a function passed as a parameter
     can be confused with a call to the function whose result is then
     passed as a parameter.  See also the functions
     `maybe_call_function()' and `probably_call_function()' in `util.c'.

*Chars:*
     According to ISO-10206 Extended Pascal, formal char parameters
     accept string values.  GPC does the necessary conversion
     implicitly.  The empty string produces a space.

*Strings and schemata:*
     Value parameter strings and schemata of known size are really
     passed by value.  Value parameter strings and schemata of unknown
     size are passed by reference, and GPC creates temporary variable
     to hold a copy of the string.

*`const' parameters:*
     If a constant value is passed to a `const' parameter, GPC assigns
     the value to a temporary variable whose address is passed.

     Even if the parameter is passed by value??? - Frank

*Typeless parameters:*
     These are denoted by `var foo' or `var foo: Void' and are
     compatible to C's `void *' parameters; the size of such entities
     is _not_ passed. Maybe we will change this in the future and pass
     the size for `var foo' parameters whereas `var foo: Void' will
     remain compatible to C.  (Same with `const' instead of `var'.)

*`CString' parameters:*
     GPC implicitly converts any string value such that the address of
     the actual string data is passed.  However, GPC did not implicitly
     append a `Chr (0)' terminator, except for string constants.  It
     does so now.


File: gpc,  Node: GPI files,  Next: AutoMake,  Prev: Parameter passing,  Up: Internals

12.5 GPI files - GNU Pascal Interfaces
======================================

   This section documents the mechanism how GPC transfers information
from the exporting modules and units to the program, module or unit
which imports (uses) the information.

   A GPI file contains a precompiled GNU Pascal interface.
"Precompiled" means in this context that the interface already has been
parsed (i.e. the front-end has done its work), but that no assembler
output has been produced yet.

   The GPI file format is an implementation-dependent (but not _too_
implementation-dependent ;-) file format for storing GNU Pascal
interfaces to be exported - Extended Pascal and PXSC module interfaces
as well as interface parts of Borland Pascal Units compiled with GNU
Pascal.

   To see what information is stored in or loaded from a GPI file, run
GPC with an additional command-line option `--debug-gpi'.  Then, GPC
will write a human-readable version of what is being stored/loaded to
the standard error device.  (See also: *Note Tree nodes::.)

   While parsing an interface, GPC stores the names of exported objects
in tree lists - in `gpc-parse.y', the bison (yacc) source of GPC's
parser, search for `handle_autoexport'.  At the end of the interface,
everything is stored in one or more GPI files.  This is called in
`gpc-parse.y' - search for `create_gpi_files'.  (See also: *Note
Language definition::, for an introduction to `gpc-parse.y')

   Everything else is done in gpc-module.c.  Here you can find the
source of `create_gpi_files()' which documents the file format:  First,
a header of 33 bytes containing the string `GNU Pascal Module/Unit
Interface\n' is stored, then the name of the primary source file of the
module as a string, then the name of the exported interface as a tree
node (see below), after that all exported names in the order as they
were stored while parsing.

   The names and the objects (i.e. constants, data types, variables and
functions) they refer to are internally represented as so-called _tree
nodes_ as defined in the files `../tree.h' and `../tree.def' from the
GNU compiler back-end.  (See also: *Note Tree nodes::.)  The names are
stored as `identifier_node's, their meanings as
`identifier_global_value's of these nodes.  The main problem when
storing tree nodes is that they form a complicated tree in memory with
a lot of circular references making it hard to decide which information
must be stored and which mustn't.

   The functions `load_tree()' and `store_tree' load/store a tree node
with the contents of all its contained pointers in a GPI file.

   Each tree node has a `tree_code' indicating what kind of information
it contains.  Each different tree node must be stored in a different
way.  See the source of `load_tree()' and `store_tree()' for details.

   Most tree nodes contain pointers to other tree nodes; therefore
`load_tree()' and `store_tree()' are recursive functions.  The
`--debug-gpi' debugging informations contains the recursion level in
parantheses, e.g. `loaded (2):' means that the loaded information was
requested by a pointer contained in a tree node requested by a pointer
contained in a tree node representing an exported symbol.

   Since this recursion can be circular (think of a record containing a
pointer to a record of the same type), we must resolve references to
tree nodes which already have been loaded.  For this reason, all nodes
are recorded in a hash buffer - see `gpi-hash.c'.

   There are some special tree_nodes (e.g. `integer_type_node' or
`NULL_TREE') which are used very often.  They have been assigned
(normally invalid) unique `tree_code's, so they can be stored in a
single byte.

   That's it.  Now you should be able to "read" GPI files using GPC's
`--debug-gpi' option.  If you encounter a case where the loaded
information differs too much from the stored information, you have
found a bug - congratulations!  What "too much" means, depends on the
object being stored in or loaded from the GPI file.  Remind that the
order things are loaded from a GPI file is the _reversed_ order things
are stored when considering _different_ recursion levels, but the
_same_ order when considering ths _same_ recursion level.


File: gpc,  Node: AutoMake,  Next: File Layout,  Prev: GPI files,  Up: Internals

12.6 GPC's AutoMake Mechanism - How it Works
============================================

   When a program/module/unit imports (uses) an interface, GPC searches
for the GPI file (see *Note GPI files::) derived from the name of the
interface.

   Case 1:  A GPI file was found.

   Each GPI file contains the name of the primary source file (normally
a `.pas' or `.p' file) of the module/unit, and the names of all
interfaces imported. GPC reads this information and invokes itself with
a command like

     gpc foo.pas -M -o foo.d

   This means: preprocess the file, and write down the name of the
object file and those of all its source files in `foo.d'.  GPC reads
`foo.d' and looks if the object file exists and if the source was
modified since the creation of the object file and the gpi file.  If
so, GPC calls itself again to compile the primary source file.  When
everything is done, the `.d' file is removed.  If there was no need to
recompile, all interfaces imported by the module/unit are processed in
the same way as this one.

   Case 2:  No GPI file was found.

   In this case, GPC derives the name of the source file from that of
the interface by trying first `interface.p', then `interface.pas'. This
will almost always work with Borland Pascal units, almost never with
Extended Pascal modules. With Extended Pascal, compile the module once
manually in order to produce a GPI file.

   All this is done by the function `gpi_open()' which uses some
auxiliary functions such as `module_must_be_recompiled()' and
`compile_module()'.

   Each time an object file is compiled or recognized as being
up-to-date, its name is stored in a temporary file with the same base
name as all the other temporary files used by GPC but the extension
`.gpc'.  When the top-level `gpc' is invoked (which calls `gpc1' later
on), it passes the name of this temporary file as an additional command
line parameter to `gpc1'.  After compilation has been completed, the
top-level `gpc' reads the temporary file and adds the new object files
to the arguments passed to the linker.

   The additional command `--amtmpfile' (not to be specified by the
user!) is passed to child GPC processes, so all compiles use the same
temporary file.

   The source for this is merely in `gpc-module.c', but there are also
some hacks in `gpc.c', additional command line options in
`lang-options.h' and `gpc-decl.c', and `gpc-defs.h' contains
declarations for the functions and global variables.


File: gpc,  Node: File Layout,  Prev: AutoMake,  Up: Internals

12.7 Files that make up GPC; Integrating GNU Pascal in GCC
==========================================================

   *NOTE:* This is not up to date.

  1. The GNU back end (gbe). Used to convert RTL into asm. Supposed to
     be language independant. Files are in the GCC source directory.

          toplev.c
          version.c
          tree.c
          print-tree.c
          stor-layout.c
          fold-const.c
          function.c
          stmt.c
          expr.c
          calls.c
          expmed.c
          explow.c
          optabs.c
          varasm.c
          rtl.c
          print-rtl.c
          rtlanal.c
          emit-rtl.c
          real.c
          dbxout.c
          sdbout.c
          dwarfout.c
          xcoffout.c
          integrate.c
          jump.c
          cse.c
          loop.c
          unroll.c
          flow.c
          stupid.c
          combine.c
          regclass.c
          local-alloc.c
          global.c
          reload.c
          reload1.c
          caller-save.c
          insn-peep.c
          reorg.c
          sched.c
          final.c
          recog.c
          reg-stack.c
          insn-opinit.c
          insn-recog.c
          insn-extract.c
          insn-output.c
          insn-emit.c
          insn-attrtab.c
          getpwd.c
          convert.c
          bc-emit.c
          bc-optab.c

     Unfortunately, some of them are not completely language independent
     and need patching for GPC. This patch is in the `p/diffs'
     subdirectory. It affects these files:

          convert.c
          dbxout.c
          expr.c
          fold-const.c
          function.c
          optabs.c
          stor-layout.c
          toplev.c

  2. Pascal language implementation files hacked from GCC source. In the
     ideal world, we would optimize them so much for Pascal that their
     GCC roots would no longer be recognizable. ;-) These files are in
     the `p/' subdirectory and are the following:

          gpcpp.c       (cccp.c)
          gpc-common.c  (c-common.c)
          gpc-convert.c (c-convert.c)
          gpc-decl.c    (c-decl.c)
          lang.c        (c-lang.c)
          gpc-lex.c     (c-lex.c)
          gpc-typeck.c  (c-typeck.c)

     Some are even reused unmodified and are still in the GCC source
     directory:

          c-aux-info.c
          c-iterate.c
          c-pragma.c

  3. GPC sources written from scratch. They are in the `p/'
     subdirectory.

          gpc-defs.h
          hash.h
          module.c
          parse.y
          util.c
          gpc.c
          gpi-hash.c
          gpi-hash.h
          circle-buf.c



File: gpc,  Node: Contributors,  Next: Copying,  Prev: Internals,  Up: Top

Appendix A Contributors to GNU Pascal.
**************************************

Jukka Virtanen
     invented GNU Pascal in March 1988, implemented the ISO-7185 and
     most of the ISO-10206 standard, etc.

Dr. Peter Gerwinski (http://agnes.dida.physik.uni-essen.de/~peter/)
     added Borland-Pascal-related and other extensions to GNU Pascal in
     summer 1995, ported GPC to EMX, does most of the development of
     the compiler since 1996, created and maintains the WWW home page,
     maintains the GNU Pascal mailing list, does some other
     administrative stuff, etc.

Jan-Jaap van der Heijden
     ported GPC to DJGPP and to Microsoft Windows 95/NT, added ELF
     support in spring 1996, solved a lot of configuration and
     compatibility problems, created the GPC FAQ, etc.

Frank Heckenbach (http://fjf.gnu.de/)
     rewrote and maintains the Run Time System since July 1997, wrote
     most of the standard units distributed with GPC (including BP
     compatibility units), wrote a large number of test programs,
     maintains the GPC To-Do list (*note To Do::) etc.

Prof. Abimbola A. Olowofoyeku ("The African Chief") (http://www.bigfoot.com/~african_chief/)
     created the original versions of many BP compatibility units in May
     1997, contributed code to other units and the Run Time System,
     helped porting GPC and the units to Cygwin and Mingw, wrote a
     number of test programs, contributed a Delphi-compatible `SysUtils'
     unit (ftp://agnes.dida.physik.uni-essen.de/home/chief/), etc.

Nick Burrett
     fixed some bugs and cleaned up GPC in May 1998, etc.

Matthias Klose
     integrated GPC into EGCS and Debian GNU/Linux in May 1998, improved
     the installation process, etc.

Alexey Volokhov
     improved the performance of GPC's module/unit support in June 1997.

Bill Currie
     implemented more Borland extensions into GPC in July 1997.

Russ Whitaker
     updated and maintains the GNU Pascal FAQ.  (*note FAQ::)

   The development of GNU Pascal profits a lot from independent
contributions (which are not part of the GNU Pascal distribution):

Anja Drewitz
     set up the archives for the GPC mailing list, *Note Mailing List
     Archives::, in September 1999.

Berend de Boer
     wrote a lot of useful documentation about Extended Pascal in 1995.

Markus Gerwinski (http://www.gerwinski.de/~markus/)
     created the drawing showing a Gnu with Blaise Pascal and helped to
     design the WWW home page in October 1996.

Nicola Girardi
     contributed a GPC unit
     (http://agnes.dida.physik.uni-essen.de/~nicola/) for the `svgalib'
     graphics library for some platforms in February 2000.

Eike Lange
     contributed units
     (ftp://agnes.dida.physik.uni-essen.de/home/lange/) to access
     MySql, GNU DBM and PostgreSQL data bases in August 2000.

Prof. Phil Nelson
     created a bug reporting system for GPC in October 1996.

Robert Hoehne (http://www.tu-chemnitz.de/~sho/rho/)
     wrote RHIDE (http://www.tu-chemnitz.de/~rho/rhide.html), an
     integrated development environment for GNU compilers running under
     Dos (DJGPP) and Linux, and added support for GNU Pascal in autumn
     1996.

Sven Hilscher
     wrote a BP compatible `Graph' unit for some platforms, called
     BGI2GRX
     (ftp://agnes.dida.physik.uni-essen.de/~gnu-pascal/contrib/), in
     December 1996.

Dario Anzani ("Predator Zeta") (http://www.geocities.com/SiliconValley/Vista/6573)
     contributed documentation about the use of assembler in GNU Pascal
     in May 1997.

Lluis de Yzaguirre i Maura
     set up a HTML version of the GNU Pascal mailing list archives,
     *Note Mailing List Archives::, in September 1997.

`(-:---------:-)'
     This space is reserved for _your_ name. ;-) Please contact us at
     the GPC mailing list, *Note Mailing List::, if you have something
     interesting for us.

   We thank everybody who supports us by reporting bugs, contributing
knowledge and good ideas, donating development tools, and giving us the
opportunity to test GPC on a large variety of systems. We are
particularly indebted (in alphabetical order, individuals first) to

Sietse Achterop, Geoffrey Arnold, Uwe Bauermann, Ariel Bendersky, Pablo
Bendersky, John Blakeney, Ernst-Ludwig Bohnen, Nils Bokermann, Patrice
Bouchand, Jim Brander, Matze Braun, J. David Bryan, Ricky W. Butler,
Dr. E. Buxbaum, Larry Carter, Janet Casey, Romain Chantereau, Emmanuel
Chaput, Carl Eric Codere, Jean-Philippe Combe, F. Couperin, Miklos
Cserzo, Tim Currie, Stefan A. Deutscher, Thomas Dunbar, Andreas
Eckleder, Sven Engelhardt, Klaus Espenlaub, Toby Ewing, Joachim Falk,
David Fiddes, Alfredo Cesar Fontana, Kevin A. Foss, Marius Gedminas,
Nicholas Geovanis, Jose Oliver Gil, Jakob Heinemann, Thorsten
Hindermann, Honda Hirotaka, Mason Ip, Andreas Jaeger, David James,
Nathalie Jarosz, Niels Kristian Bech Jensen, Achim Kalwa, Christine
Karow, Tim Kaulmann, Victor Khimenko, Russell King, Prof. Donald E.
Knuth, Tomasz Kowaltowski, Peter Ulrich Kruppa, Jochen Kuepper,
Krzysztof Kwapien, Randy Latimer, Olivier Lecarme, Wren Lee, Martin
Liddle, Kennith Linder, Stephen Lindholm, Orlando Llanes, Miguel Lobo,
Benedict Lofstedt, John Logsdon, Maurice Lombardi, Dmitry S. Luhtionov,
Jesper Lund, Martin Maechler, Claude Marinier, Michael Meeks, Clyde
Meli, Axel Mellinger, Jeff Miller, John Miller, Russell Minnich, Rudy
Moddemeijer, Jason Moore, Scott A. Moore, Pierre Muller, Andreas
Neumann, Christian Neumann, Gerhard Olejniczak, Alexandre Oliva, Ole
Osterby, Klaus Friis Ostergaard, Jean-Marc Ottorini, Matija Papec,
Miguel A. Alonso Pardo, Andris Pavenis, Robert R. Payne, Opie Pecheux,
Jose M. Perez, Ronald Perrella, Pierre Phaneuf, Nuno Pinhao, Larry
Poorman, Stuart Pope, Huge Rademaker, Mike Reid, Leon Renkema, John L.
Ries, Phil Robertson, Jim Roland, Marten Jan de Ruiter, Carl-Johan
Schenstrom, Thomas D. Schneider, George Shapovalov, Richard Sharman,
Pat Sharp, Arcadio Alivio Sincero, Tomas Srb, David Starner, Andrew
Stribblehill, Mark Taylor, Robin S. Thompson, Ian Thurlbeck, Ivan
Torshin, Bernhard Tschirren, Kresimir Veselic, Alejandro Villarroel,
Raymond Wang, Peter Weber, Christian Wendt, Gareth Wilson, Marc van
Woerkom, Michael Worsley, Takashi Yamanoue, George L. Yang, Salaam
Yitbarek, Dafi Yondra, Eli Zaretskii, Mariusz Zynel, the `BIP' at the
`University of Birmingham, UK', the `Institut fuer Festkoerperforschung
(IFF)' at the `Forschungszentrum Juelich', Germany,

and everybody we might have forgotten to mention here.  Thanks to all
of you!

   GNU Pascal is based on GNU CC by Richard Stallman.  Several people
have contributed to GNU CC:

   * The idea of using RTL and some of the optimization ideas came from
     the program PO written at the University of Arizona by Jack
     Davidson and Christopher Fraser.  See "Register Allocation and
     Exhaustive Peephole Optimization", Software Practice and
     Experience 14 (9), Sept. 1984, 857-866.

   * Paul Rubin wrote most of the preprocessor.

   * Leonard Tower wrote parts of the parser, RTL generator, and RTL
     definitions, and of the Vax machine description.

   * Ted Lemon wrote parts of the RTL reader and printer.

   * Jim Wilson implemented loop strength reduction and some other loop
     optimizations.

   * Nobuyuki Hikichi of Software Research Associates, Tokyo,
     contributed the support for the Sony NEWS machine.

   * Charles LaBrec contributed the support for the Integrated Solutions
     68020 system.

   * Michael Tiemann of Cygnus Support wrote the support for inline
     functions and instruction scheduling.  Also the descriptions of the
     National Semiconductor 32000 series cpu, the SPARC cpu and part of
     the Motorola 88000 cpu.

   * Jan Stein of the Chalmers Computer Society provided support for
     Genix, as well as part of the 32000 machine description.

   * Randy Smith finished the Sun FPA support.

   * Robert Brown implemented the support for Encore 32000 systems.

   * David Kashtan of SRI adapted GNU CC to VMS.

   * Alex Crain provided changes for the 3b1.

   * Greg Satz and Chris Hanson assisted in making GNU CC work on HP-UX
     for the 9000 series 300.

   * William Schelter did most of the work on the Intel 80386 support.

   * Christopher Smith did the port for Convex machines.

   * Paul Petersen wrote the machine description for the Alliant FX/8.

   * Dario Dariol contributed the four varieties of sample programs that
     print a copy of their source.

   * Alain Lichnewsky ported GNU CC to the Mips cpu.

   * Devon Bowen, Dale Wiles and Kevin Zachmann ported GNU CC to the
     Tahoe.

   * Jonathan Stone wrote the machine description for the Pyramid
     computer.

   * Gary Miller ported GNU CC to Charles River Data Systems machines.

   * Richard Kenner of the New York University Ultracomputer Research
     Laboratory wrote the machine descriptions for the AMD 29000, the
     DEC Alpha, the IBM RT PC, and the IBM RS/6000 as well as the
     support for instruction attributes.  He also made changes to
     better support RISC processors including changes to common
     subexpression elimination, strength reduction, function calling
     sequence handling, and condition code support, in addition to
     generalizing the code for frame pointer elimination.

   * Richard Kenner and Michael Tiemann jointly developed reorg.c, the
     delay slot scheduler.

   * Mike Meissner and Tom Wood of Data General finished the port to the
     Motorola 88000.

   * Masanobu Yuhara of Fujitsu Laboratories implemented the machine
     description for the Tron architecture (specifically, the Gmicro).

   * James van Artsdalen wrote the code that makes efficient use of the
     Intel 80387 register stack.

   * Mike Meissner at the Open Software Foundation finished the port to
     the MIPS cpu, including adding ECOFF debug support, and worked on
     the Intel port for the Intel 80386 cpu.

   * Ron Guilmette implemented the `protoize' and `unprotoize' tools,
     the support for Dwarf symbolic debugging information, and much of
     the support for System V Release 4.  He has also worked heavily on
     the Intel 386 and 860 support.

   * Torbjorn Granlund implemented multiply- and divide-by-constant
     optimization, improved long long support, and improved leaf
     function register allocation.

   * Mike Stump implemented the support for Elxsi 64 bit CPU.

   * John Wehle added the machine description for the Western Electric
     32000 processor used in several 3b series machines (no relation to
     the National Semiconductor 32000 processor).



File: gpc,  Node: Copying,  Next: GNU,  Prev: Contributors,  Up: Top

Appendix B GNU GENERAL PUBLIC LICENSE
*************************************

                         Version 2, June 1991
     Copyright (C) 1989, 1991 Free Software Foundation, Inc.
     59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
     
     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.

Preamble
========

   The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software - to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.)  You can apply it to
your programs, too.

   When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it in
new free programs; and that you know you can do these things.

   To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

   For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

   We protect your rights with two steps: (1) copyright the software,
and (2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

   Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

   Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

   The precise terms and conditions for copying, distribution and
modification follow.

    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  0. This License applies to any program or other work which contains a
     notice placed by the copyright holder saying it may be distributed
     under the terms of this General Public License.  The "Program",
     below, refers to any such program or work, and a "work based on
     the Program" means either the Program or any derivative work under
     copyright law: that is to say, a work containing the Program or a
     portion of it, either verbatim or with modifications and/or
     translated into another language.  (Hereinafter, translation is
     included without limitation in the term "modification".)  Each
     licensee is addressed as "you".

     Activities other than copying, distribution and modification are
     not covered by this License; they are outside its scope.  The act
     of running the Program is not restricted, and the output from the
     Program is covered only if its contents constitute a work based on
     the Program (independent of having been made by running the
     Program).  Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
     source code as you receive it, in any medium, provided that you
     conspicuously and appropriately publish on each copy an appropriate
     copyright notice and disclaimer of warranty; keep intact all the
     notices that refer to this License and to the absence of any
     warranty; and give any other recipients of the Program a copy of
     this License along with the Program.

     You may charge a fee for the physical act of transferring a copy,
     and you may at your option offer warranty protection in exchange
     for a fee.

  2. You may modify your copy or copies of the Program or any portion
     of it, thus forming a work based on the Program, and copy and
     distribute such modifications or work under the terms of Section 1
     above, provided that you also meet all of these conditions:

       a. You must cause the modified files to carry prominent notices
          stating that you changed the files and the date of any change.

       b. You must cause any work that you distribute or publish, that
          in whole or in part contains or is derived from the Program
          or any part thereof, to be licensed as a whole at no charge
          to all third parties under the terms of this License.

       c. If the modified program normally reads commands interactively
          when run, you must cause it, when started running for such
          interactive use in the most ordinary way, to print or display
          an announcement including an appropriate copyright notice and
          a notice that there is no warranty (or else, saying that you
          provide a warranty) and that users may redistribute the
          program under these conditions, and telling the user how to
          view a copy of this License.  (Exception: if the Program
          itself is interactive but does not normally print such an
          announcement, your work based on the Program is not required
          to print an announcement.)

     These requirements apply to the modified work as a whole.  If
     identifiable sections of that work are not derived from the
     Program, and can be reasonably considered independent and separate
     works in themselves, then this License, and its terms, do not
     apply to those sections when you distribute them as separate
     works.  But when you distribute the same sections as part of a
     whole which is a work based on the Program, the distribution of
     the whole must be on the terms of this License, whose permissions
     for other licensees extend to the entire whole, and thus to each
     and every part regardless of who wrote it.

     Thus, it is not the intent of this section to claim rights or
     contest your rights to work written entirely by you; rather, the
     intent is to exercise the right to control the distribution of
     derivative or collective works based on the Program.

     In addition, mere aggregation of another work not based on the
     Program with the Program (or with a work based on the Program) on
     a volume of a storage or distribution medium does not bring the
     other work under the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
     under Section 2) in object code or executable form under the terms
     of Sections 1 and 2 above provided that you also do one of the
     following:

       a. Accompany it with the complete corresponding machine-readable
          source code, which must be distributed under the terms of
          Sections 1 and 2 above on a medium customarily used for
          software interchange; or,

       b. Accompany it with a written offer, valid for at least three
          years, to give any third party, for a charge no more than your
          cost of physically performing source distribution, a complete
          machine-readable copy of the corresponding source code, to be
          distributed under the terms of Sections 1 and 2 above on a
          medium customarily used for software interchange; or,

       c. Accompany it with the information you received as to the offer
          to distribute corresponding source code.  (This alternative is
          allowed only for noncommercial distribution and only if you
          received the program in object code or executable form with
          such an offer, in accord with Subsection b above.)

     The source code for a work means the preferred form of the work for
     making modifications to it.  For an executable work, complete
     source code means all the source code for all modules it contains,
     plus any associated interface definition files, plus the scripts
     used to control compilation and installation of the executable.
     However, as a special exception, the source code distributed need
     not include anything that is normally distributed (in either
     source or binary form) with the major components (compiler,
     kernel, and so on) of the operating system on which the executable
     runs, unless that component itself accompanies the executable.

     If distribution of executable or object code is made by offering
     access to copy from a designated place, then offering equivalent
     access to copy the source code from the same place counts as
     distribution of the source code, even though third parties are not
     compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
     except as expressly provided under this License.  Any attempt
     otherwise to copy, modify, sublicense or distribute the Program is
     void, and will automatically terminate your rights under this
     License.  However, parties who have received copies, or rights,
     from you under this License will not have their licenses
     terminated so long as such parties remain in full compliance.

  5. You are not required to accept this License, since you have not
     signed it.  However, nothing else grants you permission to modify
     or distribute the Program or its derivative works.  These actions
     are prohibited by law if you do not accept this License.
     Therefore, by modifying or distributing the Program (or any work
     based on the Program), you indicate your acceptance of this
     License to do so, and all its terms and conditions for copying,
     distributing or modifying the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
     Program), the recipient automatically receives a license from the
     original licensor to copy, distribute or modify the Program
     subject to these terms and conditions.  You may not impose any
     further restrictions on the recipients' exercise of the rights
     granted herein.  You are not responsible for enforcing compliance
     by third parties to this License.

  7. If, as a consequence of a court judgment or allegation of patent
     infringement or for any other reason (not limited to patent
     issues), conditions are imposed on you (whether by court order,
     agreement or otherwise) that contradict the conditions of this
     License, they do not excuse you from the conditions of this
     License.  If you cannot distribute so as to satisfy simultaneously
     your obligations under this License and any other pertinent
     obligations, then as a consequence you may not distribute the
     Program at all.  For example, if a patent license would not permit
     royalty-free redistribution of the Program by all those who
     receive copies directly or indirectly through you, then the only
     way you could satisfy both it and this License would be to refrain
     entirely from distribution of the Program.

     If any portion of this section is held invalid or unenforceable
     under any particular circumstance, the balance of the section is
     intended to apply and the section as a whole is intended to apply
     in other circumstances.

     It is not the purpose of this section to induce you to infringe any
     patents or other property right claims or to contest validity of
     any such claims; this section has the sole purpose of protecting
     the integrity of the free software distribution system, which is
     implemented by public license practices.  Many people have made
     generous contributions to the wide range of software distributed
     through that system in reliance on consistent application of that
     system; it is up to the author/donor to decide if he or she is
     willing to distribute software through any other system and a
     licensee cannot impose that choice.

     This section is intended to make thoroughly clear what is believed
     to be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
     certain countries either by patents or by copyrighted interfaces,
     the original copyright holder who places the Program under this
     License may add an explicit geographical distribution limitation
     excluding those countries, so that distribution is permitted only
     in or among countries not thus excluded.  In such case, this
     License incorporates the limitation as if written in the body of
     this License.

  9. The Free Software Foundation may publish revised and/or new
     versions of the General Public License from time to time.  Such
     new versions will be similar in spirit to the present version, but
     may differ in detail to address new problems or concerns.

     Each version is given a distinguishing version number.  If the
     Program specifies a version number of this License which applies
     to it and "any later version", you have the option of following
     the terms and conditions either of that version or of any later
     version published by the Free Software Foundation.  If the Program
     does not specify a version number of this License, you may choose
     any version ever published by the Free Software Foundation.

 10. If you wish to incorporate parts of the Program into other free
     programs whose distribution conditions are different, write to the
     author to ask for permission.  For software which is copyrighted
     by the Free Software Foundation, write to the Free Software
     Foundation; we sometimes make exceptions for this.  Our decision
     will be guided by the two goals of preserving the free status of
     all derivatives of our free software and of promoting the sharing
     and reuse of software generally.

                                NO WARRANTY

 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
     WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
     LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
     HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
     WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE
     QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
     PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
     SERVICING, REPAIR OR CORRECTION.

 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
     MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
     LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
     INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
     INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
     DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
     OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
     OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
     ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

                      END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs
=============================================

   If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.

   To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

     ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
     Copyright (C) 20YY  NAME OF AUTHOR
     
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
     
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

   Also add information on how to contact you by electronic and paper
mail.

   If the program is interactive, make it output a short notice like
this when it starts in an interactive mode:

     Gnomovision version 69, Copyright (C) 20YY NAME OF AUTHOR
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
     type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.

   The hypothetical commands `show w' and `show c' should show the
appropriate parts of the General Public License.  Of course, the
commands you use may be called something other than `show w' and `show
c'; they could even be mouse-clicks or menu items - whatever suits your
program.

   You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the program,
if necessary.  Here is a sample; alter the names:

     Yoyodyne, Inc., hereby disclaims all copyright interest in the program
     `Gnomovision' (which makes passes at compilers) written by James Hacker.
     
     SIGNATURE OF TY COON, 1 April 1989
     Ty Coon, President of Vice

   This General Public License does not permit incorporating your
program into proprietary programs.  If your program is a subroutine
library, you may consider it more useful to permit linking proprietary
applications with the library.  If this is what you want to do, use the
GNU Lesser General Public License instead of this License.


File: gpc,  Node: GNU,  Next: GPC Index,  Prev: Copying,  Up: Top

Appendix C The GNU Project.
***************************

   GNU Pascal is part of the GNU project which was founded by Richard
Stallman in 1984. The aim of the GNU project is to provide a complete
operating system with editors, compilers etc. as "Free Software".

   People often confuse _Free Software_ with _public domain software_
or have other wrong information about the GNU project. If you want to
know it definitely, please read the *GNU General Public License*
(http://www.gnu.org/copyleft/gpl.html).

   For even more information, please consult the official *GNU home
page* of the _Free Software Foundation (FSF)_,

   - `http://www.gnu.org/' (USA),

   - `http://home.pages.de/~GNU/' (mirror in Germany),

   - [more mirror sites]
     (http://home.pages.de/~GNU/server/list-mirrors.html).

   Some small notes about common misunderstandings follow.

   * It is legal to compile commercial, including non-free, programs
     written in Pascal with GNU Pascal. They do _not_ automatically
     become Free Software themselves.

   * "Free" is opposed to "proprietary", but _not_ opposed to
     "commercial". Free Softare can be - and is in fact - distributed
     commercially for a real price. In contrast, most non-commercial
     software does _not_ meet the open source criteria
     (http://www.opensource.org/osd.html) and thus does _not_ qualify
     as Free Software.

   * When you modify a free program released under the *GNU General
     Public License* (http://www.gnu.org/copyleft/gpl.html), e.g. the
     GNU Pascal compiler itself, your modified work will become Free
     Software, too.

   * When using libraries for writing proprietary programs, check the
     libraries' licenses carefully. The _GNU Lesser General Public
     License_ (http://www.gnu.org/copyleft/lesser.html) allows linking
     a library to non-free software under certain conditions, the
     ordinary _GNU General Public License_ does not.

   * It is legal to charge a fee for distributing Free Software. If
     somebody sold you a copy of GNU Pascal you could have got without
     paying for it as well, that's in agreement with the _GNU General
     Public License_.

   * However if somebody wants you to sign an agreement that you won't
     re-distribute the Free Software you have got, it would be illegal.
     That person would lose the right to use and distribute that Free
     Software.

   * The preferred form to distribute Free Software is in source code.
     This ensures that everybody has the freedom to customize the
     software or to fix bugs by themselves. When we also distribute GNU
     Pascal binaries we do it only to simplify installation and to
     encourage its use.

* Menu:

* Manifesto::  The GNU Manifesto
* Funding::    How to help assure funding for Free Software


File: gpc,  Node: Manifesto,  Next: Funding,  Up: GNU

C.1 The GNU Manifesto
=====================

     The GNU Manifesto which appears below was written by Richard
     Stallman at the beginning of the GNU project, to ask for
     participation and support.  For the first few years, it was
     updated in minor ways to account for developments, but now it
     seems best to leave it unchanged as most people have seen it.

     Since that time, we have learned about certain common
     misunderstandings that different wording could help avoid.
     Footnotes added in 1993 help clarify these points.

     For up-to-date information about the available GNU software,
     please see the latest issue of the GNU's Bulletin.  The list is
     much too long to include here.

* Menu:

* Gnu is Not Unix::           What's GNU?  Gnu's Not Unix!
* Why GNU::                   Why I Must Write GNU
* GNU Unix Compatibility::    Why GNU Will Be Compatible with Unix
* GNU Availability::          How GNU Will Be Available
* Why Help GNU::              Why Many Other Programmers Want to Help
* How To Contribute to GNU::  How You Can Contribute
* GNU Benefits::              Why All Computer Users Will Benefit
* Objections to GNU::         Some Easily Rebutted Objections to GNU's Goals


File: gpc,  Node: Gnu is Not Unix,  Next: Why GNU,  Up: Manifesto

C.1.1 What's GNU?  Gnu's Not Unix!
----------------------------------

   GNU, which stands for Gnu's Not Unix, is the name for the complete
Unix-compatible software system which I am writing so that I can give it
away free to everyone who can use it.(1) Several other volunteers are
helping me.  Contributions of time, money, programs and equipment are
greatly needed.

   So far we have an Emacs text editor with Lisp for writing editor
commands, a source level debugger, a yacc-compatible parser generator,
a linker, and around 35 utilities.  A shell (command interpreter) is
nearly completed.  A new portable optimizing C compiler has compiled
itself and may be released this year.  An initial kernel exists but
many more features are needed to emulate Unix.  When the kernel and
compiler are finished, it will be possible to distribute a GNU system
suitable for program development.  We will use TeX as our text
formatter, but an nroff is being worked on.  We will use the free,
portable X window system as well.  After this we will add a portable
Common Lisp, an Empire game, a spreadsheet, and hundreds of other
things, plus on-line documentation.  We hope to supply, eventually,
everything useful that normally comes with a Unix system, and more.

   GNU will be able to run Unix programs, but will not be identical to
Unix.  We will make all improvements that are convenient, based on our
experience with other operating systems.  In particular, we plan to
have longer file names, file version numbers, a crashproof file system,
file name completion perhaps, terminal-independent display support, and
perhaps eventually a Lisp-based window system through which several
Lisp programs and ordinary Unix programs can share a screen.  Both C
and Lisp will be available as system programming languages.  We will
try to support UUCP, MIT Chaosnet, and Internet protocols for
communication.

   GNU is aimed initially at machines in the 68000/16000 class with
virtual memory, because they are the easiest machines to make it run
on.  The extra effort to make it run on smaller machines will be left
to someone who wants to use it on them.

   To avoid horrible confusion, please pronounce the `G' in the word
`GNU' when it is the name of this project.

   ---------- Footnotes ----------

   (1) The wording here was careless.  The intention was that nobody
would have to pay for _permission_ to use the GNU system.  But the
words don't make this clear, and people often interpret them as saying
that copies of GNU should always be distributed at little or no charge.
That was never the intent; later on, the manifesto mentions the
possibility of companies providing the service of distribution for a
profit.  Subsequently I have learned to distinguish carefully between
"free" in the sense of freedom and "free" in the sense of price.  Free
software is software that users have the freedom to distribute and
change.  Some users may obtain copies at no charge, while others pay to
obtain copies - and if the funds help support improving the software,
so much the better.  The important thing is that everyone who has a
copy has the freedom to cooperate with others in using it.


File: gpc,  Node: Why GNU,  Next: GNU Unix Compatibility,  Prev: Gnu is Not Unix,  Up: Manifesto

C.1.2 Why I Must Write GNU
--------------------------

   I consider that the golden rule requires that if I like a program I
must share it with other people who like it.  Software sellers want to
divide the users and conquer them, making each user agree not to share
with others.  I refuse to break solidarity with other users in this
way.  I cannot in good conscience sign a nondisclosure agreement or a
software license agreement.  For years I worked within the Artificial
Intelligence Lab to resist such tendencies and other inhospitalities,
but eventually they had gone too far: I could not remain in an
institution where such things are done for me against my will.

   So that I can continue to use computers without dishonor, I have
decided to put together a sufficient body of free software so that I
will be able to get along without any software that is not free.  I
have resigned from the AI lab to deny MIT any legal excuse to prevent
me from giving GNU away.


File: gpc,  Node: GNU Unix Compatibility,  Next: GNU Availability,  Prev: Why GNU,  Up: Manifesto

C.1.3 Why GNU Will Be Compatible with Unix
------------------------------------------

   Unix is not my ideal system, but it is not too bad.  The essential
features of Unix seem to be good ones, and I think I can fill in what
Unix lacks without spoiling them.  And a system compatible with Unix
would be convenient for many other people to adopt.


File: gpc,  Node: GNU Availability,  Next: Why Help GNU,  Prev: GNU Unix Compatibility,  Up: Manifesto

C.1.4 How GNU Will Be Available
-------------------------------

   GNU is not in the public domain.  Everyone will be permitted to
modify and redistribute GNU, but no distributor will be allowed to
restrict its further redistribution.  That is to say, proprietary
modifications will not be allowed.  I want to make sure that all
versions of GNU remain free.


File: gpc,  Node: Why Help GNU,  Next: How To Contribute to GNU,  Prev: GNU Availability,  Up: Manifesto

C.1.5 Why Many Other Programmers Want to Help
---------------------------------------------

   I have found many other programmers who are excited about GNU and
want to help.

   Many programmers are unhappy about the commercialization of system
software.  It may enable them to make more money, but it requires them
to feel in conflict with other programmers in general rather than feel
as comrades.  The fundamental act of friendship among programmers is the
sharing of programs; marketing arrangements now typically used
essentially forbid programmers to treat others as friends.  The
purchaser of software must choose between friendship and obeying the
law.  Naturally, many decide that friendship is more important.  But
those who believe in law often do not feel at ease with either choice.
They become cynical and think that programming is just a way of making
money.

   By working on and using GNU rather than proprietary programs, we can
be hospitable to everyone and obey the law.  In addition, GNU serves as
an example to inspire and a banner to rally others to join us in
sharing.  This can give us a feeling of harmony which is impossible if
we use software that is not free.  For about half the programmers I
talk to, this is an important happiness that money cannot replace.


File: gpc,  Node: How To Contribute to GNU,  Next: GNU Benefits,  Prev: Why Help GNU,  Up: Manifesto

C.1.6 How You Can Contribute
----------------------------

   I am asking computer manufacturers for donations of machines and
money.  I'm asking individuals for donations of programs and work.

   One consequence you can expect if you donate machines is that GNU
will run on them at an early date.  The machines should be complete,
ready to use systems, approved for use in a residential area, and not
in need of sophisticated cooling or power.

   I have found very many programmers eager to contribute part-time
work for GNU.  For most projects, such part-time distributed work would
be very hard to coordinate; the independently-written parts would not
work together.  But for the particular task of replacing Unix, this
problem is absent.  A complete Unix system contains hundreds of utility
programs, each of which is documented separately.  Most interface
specifications are fixed by Unix compatibility.  If each contributor
can write a compatible replacement for a single Unix utility, and make
it work properly in place of the original on a Unix system, then these
utilities will work right when put together.  Even allowing for Murphy
to create a few unexpected problems, assembling these components will
be a feasible task.  (The kernel will require closer communication and
will be worked on by a small, tight group.)

   If I get donations of money, I may be able to hire a few people full
or part time.  The salary won't be high by programmers' standards, but
I'm looking for people for whom building community spirit is as
important as making money.  I view this as a way of enabling dedicated
people to devote their full energies to working on GNU by sparing them
the need to make a living in another way.


File: gpc,  Node: GNU Benefits,  Next: Objections to GNU,  Prev: How To Contribute to GNU,  Up: Manifesto

C.1.7 Why All Computer Users Will Benefit
-----------------------------------------

   Once GNU is written, everyone will be able to obtain good system
software free, just like air.(1)

   This means much more than just saving everyone the price of a Unix
license.  It means that much wasteful duplication of system programming
effort will be avoided.  This effort can go instead into advancing the
state of the art.

   Complete system sources will be available to everyone.  As a result,
a user who needs changes in the system will always be free to make them
himself, or hire any available programmer or company to make them for
him.  Users will no longer be at the mercy of one programmer or company
which owns the sources and is in sole position to make changes.

   Schools will be able to provide a much more educational environment
by encouraging all students to study and improve the system code.
Harvard's computer lab used to have the policy that no program could be
installed on the system if its sources were not on public display, and
upheld it by actually refusing to install certain programs.  I was very
much inspired by this.

   Finally, the overhead of considering who owns the system software
and what one is or is not entitled to do with it will be lifted.

   Arrangements to make people pay for using a program, including
licensing of copies, always incur a tremendous cost to society through
the cumbersome mechanisms necessary to figure out how much (that is,
which programs) a person must pay for.  And only a police state can
force everyone to obey them.  Consider a space station where air must
be manufactured at great cost: charging each breather per liter of air
may be fair, but wearing the metered gas mask all day and all night is
intolerable even if everyone can afford to pay the air bill.  And the
TV cameras everywhere to see if you ever take the mask off are
outrageous.  It's better to support the air plant with a head tax and
chuck the masks.

   Copying all or parts of a program is as natural to a programmer as
breathing, and as productive.  It ought to be as free.

   ---------- Footnotes ----------

   (1) This is another place I failed to distinguish carefully between
the two different meanings of "free".  The statement as it stands is
not false - you can get copies of GNU software at no charge, from your
friends or over the net.  But it does suggest the wrong idea.


File: gpc,  Node: Objections to GNU,  Prev: GNU Benefits,  Up: Manifesto

C.1.8 Some Easily Rebutted Objections to GNU's Goals
----------------------------------------------------

     "Nobody will use it if it is free, because that means they can't
     rely on any support."

     "You have to charge for the program to pay for providing the
     support."

   If people would rather pay for GNU plus service than get GNU free
without service, a company to provide just service to people who have
obtained GNU free ought to be profitable.(1)

   We must distinguish between support in the form of real programming
work and mere handholding.  The former is something one cannot rely on
from a software vendor.  If your problem is not shared by enough
people, the vendor will tell you to get lost.

   If your business needs to be able to rely on support, the only way
is to have all the necessary sources and tools.  Then you can hire any
available person to fix your problem; you are not at the mercy of any
individual.  With Unix, the price of sources puts this out of
consideration for most businesses.  With GNU this will be easy.  It is
still possible for there to be no available competent person, but this
problem cannot be blamed on distribution arrangements.  GNU does not
eliminate all the world's problems, only some of them.

   Meanwhile, the users who know nothing about computers need
handholding: doing things for them which they could easily do
themselves but don't know how.

   Such services could be provided by companies that sell just
hand-holding and repair service.  If it is true that users would rather
spend money and get a product with service, they will also be willing
to buy the service having got the product free.  The service companies
will compete in quality and price; users will not be tied to any
particular one.  Meanwhile, those of us who don't need the service
should be able to use the program without paying for the service.

     "You cannot reach many people without advertising, and you must
     charge for the program to support that."

     "It's no use advertising a program people can get free."

   There are various forms of free or very cheap publicity that can be
used to inform numbers of computer users about something like GNU.  But
it may be true that one can reach more microcomputer users with
advertising.  If this is really so, a business which advertises the
service of copying and mailing GNU for a fee ought to be successful
enough to pay for its advertising and more.  This way, only the users
who benefit from the advertising pay for it.

   On the other hand, if many people get GNU from their friends, and
such companies don't succeed, this will show that advertising was not
really necessary to spread GNU.  Why is it that free market advocates
don't want to let the free market decide this?(2)

     "My company needs a proprietary operating system to get a
     competitive edge."

   GNU will remove operating system software from the realm of
competition.  You will not be able to get an edge in this area, but
neither will your competitors be able to get an edge over you.  You and
they will compete in other areas, while benefiting mutually in this
one.  If your business is selling an operating system, you will not
like GNU, but that's tough on you.  If your business is something else,
GNU can save you from being pushed into the expensive business of
selling operating systems.

   I would like to see GNU development supported by gifts from many
manufacturers and users, reducing the cost to each.(3)

     "Don't programmers deserve a reward for their creativity?"

   If anything deserves a reward, it is social contribution.
Creativity can be a social contribution, but only in so far as society
is free to use the results.  If programmers deserve to be rewarded for
creating innovative programs, by the same token they deserve to be
punished if they restrict the use of these programs.

     "Shouldn't a programmer be able to ask for a reward for his
     creativity?"

   There is nothing wrong with wanting pay for work, or seeking to
maximize one's income, as long as one does not use means that are
destructive.  But the means customary in the field of software today
are based on destruction.

   Extracting money from users of a program by restricting their use of
it is destructive because the restrictions reduce the amount and the
ways that the program can be used.  This reduces the amount of wealth
that humanity derives from the program.  When there is a deliberate
choice to restrict, the harmful consequences are deliberate destruction.

   The reason a good citizen does not use such destructive means to
become wealthier is that, if everyone did so, we would all become
poorer from the mutual destructiveness.  This is Kantian ethics; or,
the Golden Rule.  Since I do not like the consequences that result if
everyone hoards information, I am required to consider it wrong for one
to do so.  Specifically, the desire to be rewarded for one's creativity
does not justify depriving the world in general of all or part of that
creativity.

     "Won't programmers starve?"

   I could answer that nobody is forced to be a programmer.  Most of us
cannot manage to get any money for standing on the street and making
faces.  But we are not, as a result, condemned to spend our lives
standing on the street making faces, and starving.  We do something
else.

   But that is the wrong answer because it accepts the questioner's
implicit assumption: that without ownership of software, programmers
cannot possibly be paid a cent.  Supposedly it is all or nothing.

   The real reason programmers will not starve is that it will still be
possible for them to get paid for programming; just not paid as much as
now.

   Restricting copying is not the only basis for business in software.
It is the most common basis because it brings in the most money.  If it
were prohibited, or rejected by the customer, software business would
move to other bases of organization which are now used less often.
There are always numerous ways to organize any kind of business.

   Probably programming will not be as lucrative on the new basis as it
is now.  But that is not an argument against the change.  It is not
considered an injustice that sales clerks make the salaries that they
now do.  If programmers made the same, that would not be an injustice
either.  (In practice they would still make considerably more than
that.)

     "Don't people have a right to control how their creativity is
     used?"

   "Control over the use of one's ideas" really constitutes control over
other people's lives; and it is usually used to make their lives more
difficult.

   People who have studied the issue of intellectual property rights
carefully (such as lawyers) say that there is no intrinsic right to
intellectual property.  The kinds of supposed intellectual property
rights that the government recognizes were created by specific acts of
legislation for specific purposes.

   For example, the patent system was established to encourage
inventors to disclose the details of their inventions.  Its purpose was
to help society rather than to help inventors.  At the time, the life
span of 17 years for a patent was short compared with the rate of
advance of the state of the art.  Since patents are an issue only among
manufacturers, for whom the cost and effort of a license agreement are
small compared with setting up production, the patents often do not do
much harm.  They do not obstruct most individuals who use patented
products.

   The idea of copyright did not exist in ancient times, when authors
frequently copied other authors at length in works of non-fiction.  This
practice was useful, and is the only way many authors' works have
survived even in part.  The copyright system was created expressly for
the purpose of encouraging authorship.  In the domain for which it was
invented - books, which could be copied economically only on a printing
press - it did little harm, and did not obstruct most of the individuals
who read the books.

   All intellectual property rights are just licenses granted by society
because it was thought, rightly or wrongly, that society as a whole
would benefit by granting them.  But in any particular situation, we
have to ask: are we really better off granting such license?  What kind
of act are we licensing a person to do?

   The case of programs today is very different from that of books a
hundred years ago.  The fact that the easiest way to copy a program is
from one neighbor to another, the fact that a program has both source
code and object code which are distinct, and the fact that a program is
used rather than read and enjoyed, combine to create a situation in
which a person who enforces a copyright is harming society as a whole
both materially and spiritually; in which a person should not do so
regardless of whether the law enables him to.

     "Competition makes things get done better."

   The paradigm of competition is a race: by rewarding the winner, we
encourage everyone to run faster.  When capitalism really works this
way, it does a good job; but its defenders are wrong in assuming it
always works this way.  If the runners forget why the reward is offered
and become intent on winning, no matter how, they may find other
strategies - such as, attacking other runners.  If the runners get into
a fist fight, they will all finish late.

   Proprietary and secret software is the moral equivalent of runners
in a fist fight.  Sad to say, the only referee we've got does not seem
to object to fights; he just regulates them ("For every ten yards you
run, you can fire one shot").  He really ought to break them up, and
penalize runners for even trying to fight.

     "Won't everyone stop programming without a monetary incentive?"

   Actually, many people will program with absolutely no monetary
incentive.  Programming has an irresistible fascination for some
people, usually the people who are best at it.  There is no shortage of
professional musicians who keep at it even though they have no hope of
making a living that way.

   But really this question, though commonly asked, is not appropriate
to the situation.  Pay for programmers will not disappear, only become
less.  So the right question is, will anyone program with a reduced
monetary incentive?  My experience shows that they will.

   For more than ten years, many of the world's best programmers worked
at the Artificial Intelligence Lab for far less money than they could
have had anywhere else.  They got many kinds of non-monetary rewards:
fame and appreciation, for example.  And creativity is also fun, a
reward in itself.

   Then most of them left when offered a chance to do the same
interesting work for a lot of money.

   What the facts show is that people will program for reasons other
than riches; but if given a chance to make a lot of money as well, they
will come to expect and demand it.  Low-paying organizations do poorly
in competition with high-paying ones, but they do not have to do badly
if the high-paying ones are banned.

     "We need the programmers desperately.  If they demand that we stop
     helping our neighbors, we have to obey."

   You're never so desperate that you have to obey this sort of demand.
Remember: millions for defense, but not a cent for tribute!

     "Programmers need to make a living somehow."

   In the short run, this is true.  However, there are plenty of ways
that programmers could make a living without selling the right to use a
program.  This way is customary now because it brings programmers and
businessmen the most money, not because it is the only way to make a
living.  It is easy to find other ways if you want to find them.  Here
are a number of examples.

   A manufacturer introducing a new computer will pay for the porting of
operating systems onto the new hardware.

   The sale of teaching, hand-holding and maintenance services could
also employ programmers.

   People with new ideas could distribute programs as freeware, asking
for donations from satisfied users, or selling hand-holding services.
I have met people who are already working this way successfully.

   Users with related needs can form users' groups, and pay dues.  A
group would contract with programming companies to write programs that
the group's members would like to use.

   All sorts of development can be funded with a Software Tax:

     Suppose everyone who buys a computer has to pay x percent of the
     price as a software tax.  The government gives this to an agency
     like the NSF to spend on software development.

     But if the computer buyer makes a donation to software development
     himself, he can take a credit against the tax.  He can donate to
     the project of his own choosing - often, chosen because he hopes to
     use the results when it is done.  He can take a credit for any
     amount of donation up to the total tax he had to pay.

     The total tax rate could be decided by a vote of the payers of the
     tax, weighted according to the amount they will be taxed on.

     The consequences:

        * The computer-using community supports software development.

        * This community decides what level of support is needed.

        * Users who care which projects their share is spent on can
          choose this for themselves.

   In the long run, making programs free is a step toward the
post-scarcity world, where nobody will have to work very hard just to
make a living.  People will be free to devote themselves to activities
that are fun, such as programming, after spending the necessary ten
hours a week on required tasks such as legislation, family counseling,
robot repair and asteroid prospecting.  There will be no need to be
able to make a living from programming.

   We have already greatly reduced the amount of work that the whole
society must do for its actual productivity, but only a little of this
has translated itself into leisure for workers because much
nonproductive activity is required to accompany productive activity.
The main causes of this are bureaucracy and isometric struggles against
competition.  Free software will greatly reduce these drains in the
area of software production.  We must do this, in order for technical
gains in productivity to translate into less work for us.

   ---------- Footnotes ----------

   (1) Several such companies now exist.

   (2) The Free Software Foundation raises most of its funds from a
distribution service, although it is a charity rather than a company.
If _no one_ chooses to obtain copies by ordering from the FSF, it will
be unable to do its work.  But this does not mean that proprietary
restrictions are justified to force every user to pay.  If a small
fraction of all the users order copies from the FSF, that is sufficient
to keep the FSF afloat.  So we ask users to choose to support us in
this way.  Have you done your part?

   (3) A group of computer companies recently pooled funds to support
maintenance of the GNU C Compiler.


File: gpc,  Node: Funding,  Prev: Manifesto,  Up: GNU

C.2 Funding Free Software
=========================

   If you want to have more free software a few years from now, it makes
sense for you to help encourage people to contribute funds for its
development.  The most effective approach known is to encourage
commercial redistributors to donate.

   Users of free software systems can boost the pace of development by
encouraging for-a-fee distributors to donate part of their selling price
to free software developers - the Free Software Foundation, and others.

   The way to convince distributors to do this is to demand it and
expect it from them.  So when you compare distributors, judge them
partly by how much they give to free software development.  Show
distributors they must compete to be the one who gives the most.

   To make this approach work, you must insist on numbers that you can
compare, such as, "We will donate ten dollars to the Frobnitz project
for each disk sold."  Don't be satisfied with a vague promise, such as
"A portion of the profits are donated," since it doesn't give a basis
for comparison.

   Even a precise fraction "of the profits from this disk" is not very
meaningful, since creative accounting and unrelated business decisions
can greatly alter what fraction of the sales price counts as profit.
If the price you pay is $50, ten percent of the profit is probably less
than a dollar; it might be a few cents, or nothing at all.

   Some redistributors do development work themselves.  This is useful
too; but to keep everyone honest, you need to inquire how much they do,
and what kind.  Some kinds of development make much more long-term
difference than others.  For example, maintaining a separate version of
a program contributes very little; maintaining the standard version of a
program for the whole community contributes much.  Easy new ports
contribute little, since someone else would surely do them; difficult
ports such as adding a new CPU to the GNU C compiler contribute more;
major new features or packages contribute the most.

   By establishing the idea that supporting further development is "the
proper thing to do" when distributing free software for a fee, we can
assure a steady flow of resources into making more free software.

     Copyright (C) 1994 Free Software Foundation, Inc.
     Verbatim copying and redistribution of this section is permitted
     without royalty; alteration is not permitted.


File: gpc,  Node: GPC Index,  Prev: GNU,  Up: Top

GPC Index
*********

* Menu:

* *:                                     Complex Number Operations.
* **:                                    Complex Number Operations.
* + <1>:                                 Complex Number Operations.
* +:                                     String Operations.
* -:                                     Complex Number Operations.
* -amtmpfile:                            GPC Command Line Options.
* -autobuild:                            GPC Command Line Options.
* -autolink:                             GPC Command Line Options.
* -automake:                             GPC Command Line Options.
* -borland-char-constants:               GPC Command Line Options.
* -borland-pascal:                       GPC Command Line Options.
* -cidefine:                             GPC Command Line Options.
* -csdefine:                             GPC Command Line Options.
* -debug-gpi:                            GPC Command Line Options.
* -debug-source:                         GPC Command Line Options.
* -debug-tree:                           GPC Command Line Options.
* -delphi:                               GPC Command Line Options.
* -delphi-comments:                      GPC Command Line Options.
* -exact-compare-strings:                GPC Command Line Options.
* -executable-file-name:                 GPC Command Line Options.
* -executable-path:                      GPC Command Line Options.
* -extended-pascal:                      GPC Command Line Options.
* -extended-syntax:                      GPC Command Line Options.
* -field-widths:                         GPC Command Line Options.
* -gnu-pascal:                           GPC Command Line Options.
* -gpc-main <1>:                         Importing Libraries from Other Languages.
* -gpc-main:                             GPC Command Line Options.
* -gpi-destination-path:                 GPC Command Line Options.
* -ignore-function-results:              GPC Command Line Options.
* -implementation-only:                  GPC Command Line Options.
* -interface-only:                       GPC Command Line Options.
* -io-checking:                          GPC Command Line Options.
* -lines:                                GPC Command Line Options.
* -macros:                               GPC Command Line Options.
* -mixed-comments:                       GPC Command Line Options.
* -nested-comments:                      GPC Command Line Options.
* -no-autobuild:                         GPC Command Line Options.
* -no-autolink:                          GPC Command Line Options.
* -no-automake:                          GPC Command Line Options.
* -no-borland-char-constants:            GPC Command Line Options.
* -no-default-paths:                     GPC Command Line Options.
* -no-delphi-comments:                   GPC Command Line Options.
* -no-exact-compare-strings:             GPC Command Line Options.
* -no-executable-path:                   GPC Command Line Options.
* -no-extended-syntax:                   GPC Command Line Options.
* -no-field-widths:                      GPC Command Line Options.
* -no-ignore-function-results:           GPC Command Line Options.
* -no-io-checking:                       GPC Command Line Options.
* -no-macros:                            GPC Command Line Options.
* -no-mixed-comments:                    GPC Command Line Options.
* -no-nested-comments:                   GPC Command Line Options.
* -no-object-destination-path:           GPC Command Line Options.
* -no-object-path:                       GPC Command Line Options.
* -no-pedantic:                          GPC Command Line Options.
* -no-short-circuit:                     GPC Command Line Options.
* -no-signed-char:                       GPC Command Line Options.
* -no-stack-checking:                    GPC Command Line Options.
* -no-transparent-file-names:            GPC Command Line Options.
* -no-truncate-strings:                  GPC Command Line Options.
* -no-typed-address:                     GPC Command Line Options.
* -no-unit-destination-path:             GPC Command Line Options.
* -no-unit-path:                         GPC Command Line Options.
* -no-unsigned-char:                     GPC Command Line Options.
* -no-write-capital-exponent:            GPC Command Line Options.
* -no-write-clip-strings:                GPC Command Line Options.
* -no-write-real-blank:                  GPC Command Line Options.
* -object-destination-path:              GPC Command Line Options.
* -object-pascal:                        GPC Command Line Options.
* -object-path:                          GPC Command Line Options.
* -pascal-sc:                            GPC Command Line Options.
* -pedantic:                             GPC Command Line Options.
* -progress-bar:                         GPC Command Line Options.
* -progress-messages:                    GPC Command Line Options.
* -setlimit:                             GPC Command Line Options.
* -short-circuit:                        GPC Command Line Options.
* -signed-char:                          GPC Command Line Options.
* -stack-checking:                       GPC Command Line Options.
* -standard-pascal:                      GPC Command Line Options.
* -standard-pascal-level-0:              GPC Command Line Options.
* -transparent-file-names:               GPC Command Line Options.
* -truncate-strings:                     GPC Command Line Options.
* -typed-address:                        GPC Command Line Options.
* -unit-destination-path:                GPC Command Line Options.
* -unit-path:                            GPC Command Line Options.
* -unsigned-char:                        GPC Command Line Options.
* -uses:                                 GPC Command Line Options.
* -Wfield-name-problem:                  GPC Command Line Options.
* -Wmixed-comments:                      GPC Command Line Options.
* -Wnear-far:                            GPC Command Line Options.
* -Wnested-comments:                     GPC Command Line Options.
* -Wno-field-name-problem:               GPC Command Line Options.
* -Wno-mixed-comments:                   GPC Command Line Options.
* -Wno-near-far:                         GPC Command Line Options.
* -Wno-nested-comments:                  GPC Command Line Options.
* -Wno-object-directives:                GPC Command Line Options.
* -Wno-typed-const:                      GPC Command Line Options.
* -Wno-underscore:                       GPC Command Line Options.
* -Wno-warnings:                         GPC Command Line Options.
* -Wobject-directives:                   GPC Command Line Options.
* -write-capital-exponent:               GPC Command Line Options.
* -write-clip-strings:                   GPC Command Line Options.
* -write-real-blank:                     GPC Command Line Options.
* -Wtyped-const:                         GPC Command Line Options.
* -Wunderscore:                          GPC Command Line Options.
* -Wwarnings:                            GPC Command Line Options.
* /:                                     Complex Number Operations.
* ><:                                    Set Operations.
* Abs:                                   Abs.
* absolute <1>:                          Keywords.
* absolute:                              absolute.
* abstract <1>:                          Keywords.
* abstract:                              abstract.
* Addr:                                  Addr.
* alignment:                             AlignOf.
* Alignment, Type Implementation:        Alignment.
* AlignOf:                               AlignOf.
* all <1>:                               Keywords.
* all:                                   all.
* and <1>:                               Keywords.
* and <2>:                               and.
* and:                                   Operations for Integer and Ordinal Types.
* and then:                              and then.
* and_then <1>:                          Keywords.
* and_then:                              and_then.
* AnsiChar:                              AnsiChar.
* Append:                                Append.
* ArcTan <1>:                            ArcTan.
* ArcTan:                                Complex Number Operations.
* Arg <1>:                               Arg.
* Arg:                                   Complex Number Operations.
* array <1>:                             Keywords.
* array:                                 array.
* Array Types, Data Types:               Array Types.
* array, conformant:                     Conformant Arrays.
* array, open:                           Open Arrays.
* asm <1>:                               Keywords.
* asm:                                   asm.
* asm, Statements, Source Structure:     asm Inline.
* asmname <1>:                           Keywords.
* asmname <2>:                           asmname.
* asmname:                               Importing Libraries from Other Languages.
* Assign:                                Assign.
* Assigned:                              Assigned.
* Assignment, Statements, Source Structure: Assignment.
* attribute <1>:                         Keywords.
* attribute:                             attribute.
* AutoMake, internals:                   AutoMake.
* begin <1>:                             Keywords.
* begin:                                 begin.
* begin end, Statements, Source Structure: begin end Compound Statement.
* binary distributions, installing:      Binary Distributions.
* Bind <1>:                              Bind.
* Bind:                                  File Routines.
* bindable <1>:                          Keywords.
* bindable:                              bindable.
* Binding <1>:                           Binding.
* Binding:                               File Routines.
* BindingType:                           BindingType.
* bits:                                  BitSizeOf.
* BitSizeOf:                             BitSizeOf.
* BlockRead:                             BlockRead.
* BlockWrite:                            BlockWrite.
* Boolean:                               Boolean.
* Boolean, Intrinsic, Data Types:        Boolean (Intrinsic).
* Break:                                 Break.
* bugs:                                  Support.
* Built-in:                              Library Routines.
* Byte:                                  Byte.
* ByteBool:                              ByteBool.
* ByteCard:                              ByteCard.
* ByteInt:                               ByteInt.
* C <1>:                                 C.
* C <2>:                                 Importing Libraries from Other Languages.
* C:                                     Other Languages.
* C language:                            Importing Libraries from Other Languages.
* C_Language <1>:                        C_Language.
* C_Language:                            Importing Libraries from Other Languages.
* Card <1>:                              Card.
* Card:                                  Set Operations.
* Cardinal:                              Cardinal.
* case <1>:                              Keywords.
* case:                                  case.
* case, Statements, Source Structure:    case Statement.
* Char:                                  Char.
* Char, Intrinsic, Data Types:           Character Types.
* ChDir:                                 ChDir.
* Chr:                                   Chr.
* class <1>:                             Keywords.
* class:                                 class.
* Close:                                 Close.
* Cmplx <1>:                             Cmplx.
* Cmplx:                                 Complex Number Operations.
* command line options:                  Invoking GPC.
* Comp:                                  Comp.
* Compilation notes for specific platforms: Compilation Notes.
* compiler directives:                   Compiler Directives.
* Complex:                               Complex.
* Concat <1>:                            Concat.
* Concat:                                String Operations.
* conformant arrays, internals:          Parameter passing.
* Conjugate:                             Conjugate.
* const <1>:                             Keywords.
* const:                                 const.
* Constant Declaration, Source Structures: Constant Declaration.
* constructor <1>:                       Keywords.
* constructor:                           constructor.
* Continue:                              Continue.
* contributors:                          Contributors.
* Copy:                                  Copy.
* Cos <1>:                               Cos.
* Cos:                                   Complex Number Operations.
* cross-compilers:                       Cross-Compilers.
* crossbuilding:                         Crossbuilding.
* CString:                               CString.
* CString2String:                        CString2String.
* CStringCopyString:                     CStringCopyString.
* CVS <1>:                               Compiling GPC.
* CVS:                                   Download.
* Data Types, Definition:                Type Definition.
* Date <1>:                              Date.
* Date:                                  Date And Time Routines.
* debugging:                             Notes for Debugging.
* Dec <1>:                               Dec.
* Dec:                                   Operations for Integer and Ordinal Types.
* DefineSize:                            DefineSize.
* Delete:                                Delete.
* destructor <1>:                        Keywords.
* destructor:                            destructor.
* Dispose <1>:                           Dispose.
* Dispose:                               Memory Management Routines.
* div <1>:                               Keywords.
* div:                                   div.
* djgpp:                                 MS-DOS with DJGPP.
* do <1>:                                Keywords.
* do:                                    do.
* DOS, MS- <1>:                          MS-DOS or OS/2 with EMX.
* DOS, MS-:                              MS-DOS with DJGPP.
* Double <1>:                            Double.
* Double:                                Real Types.
* download:                              Download.
* downto <1>:                            Keywords.
* downto:                                downto.
* else <1>:                              Keywords.
* else:                                  else.
* Empty:                                 Empty.
* EMX:                                   MS-DOS or OS/2 with EMX.
* end <1>:                               Keywords.
* end:                                   end.
* endianness:                            Endianness.
* Enumerated Types, Data Types:          Enumerated Types.
* EOF:                                   EOF.
* EOLn:                                  EOLn.
* EpsReal:                               EpsReal.
* Eq:                                    Eq.
* Erase:                                 Erase.
* Exclude:                               Exclude.
* Exit:                                  Exit.
* Exp <1>:                               Exp.
* Exp:                                   Complex Number Operations.
* export <1>:                            Keywords.
* export:                                export.
* exports <1>:                           Keywords.
* exports:                               exports.
* Extend:                                Extend.
* Extended <1>:                          Extended.
* Extended:                              Real Types.
* extern <1>:                            extern.
* extern:                                Importing Libraries from Other Languages.
* external <1>:                          Keywords.
* external <2>:                          external.
* external:                              Importing Libraries from Other Languages.
* Fail:                                  Fail.
* False:                                 False.
* FAQ:                                   FAQ.
* far:                                   far.
* file <1>:                              Keywords.
* file:                                  file.
* File Layout, internals:                File Layout.
* File Types, Intrinsic, Data Types:     File Types.
* FileMode:                              FileMode.
* FilePos:                               FilePos.
* FileSize:                              FileSize.
* FillChar:                              FillChar.
* Flush:                                 Flush.
* for <1>:                               Keywords.
* for:                                   for.
* for, Statements, Source Structure:     for Statement.
* forward <1>:                           Keywords.
* forward:                               forward.
* Frac:                                  Frac.
* FrameAddress:                          FrameAddress.
* FreeMem <1>:                           FreeMem.
* FreeMem:                               Memory Management Routines.
* Frequently Asked Questions:            FAQ.
* front-end, internals <1>:              Tree nodes.
* front-end, internals:                  Language definition.
* FTP:                                   Download.
* function <1>:                          Keywords.
* function:                              function.
* function, Subroutine Declaration, Source Structure: The Function.
* functional type:                       Procedural Types.
* functions as parameters, internals:    Parameter passing.
* functions, predefined:                 Library Routines.
* GE:                                    GE.
* Get <1>:                               Get.
* Get:                                   File Routines.
* GetMem <1>:                            GetMem.
* GetMem:                                Memory Management Routines.
* GetTimeStamp <1>:                      GetTimeStamp.
* GetTimeStamp:                          Date And Time Routines.
* GNU:                                   GNU.
* GNU Pascal command line options:       Invoking GPC.
* goto <1>:                              Keywords.
* goto:                                  goto.
* goto, Statements, Source Structure:    goto Statement.
* GPC and other languages:               Other Languages.
* GPC source, internals:                 Internals.
* GPC, internals:                        Internals.
* GPI files, internals:                  GPI files.
* grammar, internals:                    Language definition.
* GT:                                    GT.
* Halt:                                  Halt.
* help:                                  Support.
* High:                                  High.
* highlights:                            Highlights.
* if <1>:                                Keywords.
* if:                                    if.
* if, Statements, Source Structure:      if Statement.
* Im <1>:                                Im.
* Im:                                    Complex Number Operations.
* implementation <1>:                    Keywords.
* implementation:                        implementation.
* import <1>:                            Keywords.
* import:                                import.
* import part <1>:                       Units.
* import part:                           Modules.
* Import Part, Source Structures:        Modules and Units.
* in <1>:                                Keywords.
* in:                                    in.
* Inc <1>:                               Inc.
* Inc:                                   Operations for Integer and Ordinal Types.
* Include:                               Include.
* Index:                                 Index.
* inherited <1>:                         Keywords.
* inherited <2>:                         inherited.
* inherited:                             OOP.
* inline <1>:                            Keywords.
* inline:                                inline.
* InOutRes:                              InOutRes.
* InOutResStr:                           InOutResStr.
* Input:                                 Input.
* Insert:                                Insert.
* installing binary distributions:       Binary Distributions.
* installing GNU Pascal:                 Installation.
* installing source distributions:       Compiling GPC.
* Int:                                   Int.
* Integer:                               Integer.
* Integer types:                         Integer Types.
* integer types, compatibility:          Integer Types and Compatibility.
* integer types, main branch:            Main Branch Integer Types.
* integer types, natural:                Natural Integer Types.
* integer types, specified size:         Integer Types with Specified Size.
* integer types, summary:                Summary of Integer Types.
* interface <1>:                         Keywords.
* interface:                             interface.
* intermediate code, internals:          Tree nodes.
* interrupt <1>:                         Keywords.
* interrupt:                             interrupt.
* IOResult:                              IOResult.
* is <1>:                                Keywords.
* is:                                    is.
* label <1>:                             Keywords.
* label:                                 label.
* Label Declaration, Source Structures:  Label Declaration.
* language definition, internals:        Language definition.
* LastPosition <1>:                      LastPosition.
* LastPosition:                          File Routines.
* LE:                                    LE.
* Length:                                Length.
* lexical analyzer, internals:           Lexical analyzer.
* Libraries:                             GPC Options.
* library <1>:                           Keywords.
* library:                               library.
* linking:                               Importing Libraries from Other Languages.
* Ln <1>:                                Ln.
* Ln:                                    Complex Number Operations.
* LoCase:                                LoCase.
* LongBool:                              LongBool.
* LongCard:                              LongCard.
* LongestBool:                           LongestBool.
* LongestCard:                           LongestCard.
* LongestInt:                            LongestInt.
* LongestReal:                           LongestReal.
* LongestWord:                           LongestWord.
* LongInt:                               LongInt.
* LongReal <1>:                          LongReal.
* LongReal:                              Real Types.
* LongWord:                              LongWord.
* Loops, Loop Control Statements:        Loop Control Statements.
* Low:                                   Low.
* LT:                                    LT.
* Machine-dependent Type Implementation: Machine-dependent Type Implementation.
* magic, internals:                      Tree nodes.
* main program:                          Importing Libraries from Other Languages.
* Mark:                                  Mark.
* Max <1>:                               Max.
* Max:                                   Operations for Integer and Ordinal Types.
* MaxChar:                               MaxChar.
* MaxInt:                                MaxInt.
* MaxReal:                               MaxReal.
* MedBool:                               MedBool.
* MedCard:                               MedCard.
* MedInt:                                MedInt.
* MedReal:                               MedReal.
* MedWord:                               MedWord.
* Min <1>:                               Min.
* Min:                                   Operations for Integer and Ordinal Types.
* MinReal:                               MinReal.
* MkDir:                                 MkDir.
* mod <1>:                               Keywords.
* mod:                                   mod.
* module <1>:                            Keywords.
* module:                                module.
* Modules, source structure:             Modules.
* Move:                                  Move.
* MoveLeft:                              MoveLeft.
* MoveRight:                             MoveRight.
* MS Windows 95/98/NT <1>:               MS Windows 95/98/NT.
* MS Windows 95/98/NT:                   Download.
* MS-DOS <1>:                            MS-DOS or OS/2 with EMX.
* MS-DOS:                                MS-DOS with DJGPP.
* Name:                                  Name.
* NE:                                    NE.
* near:                                  near.
* New <1>:                               New.
* New <2>:                               Memory Management Routines.
* New:                                   OOP.
* NewCString:                            NewCString.
* news:                                  News.
* nil <1>:                               Keywords.
* nil:                                   nil.
* not <1>:                               Keywords.
* not <2>:                               not.
* not:                                   Operations for Integer and Ordinal Types.
* Null:                                  Null.
* object <1>:                            Keywords.
* object:                                object.
* Object Types, Data Types:              Object Types.
* object-orientated programming:         OOP.
* Objects:                               Exporting GPC Libraries to Other Languages.
* Odd:                                   Odd.
* of <1>:                                Keywords.
* of:                                    of.
* only <1>:                              Keywords.
* only:                                  only.
* OOP:                                   OOP.
* operator <1>:                          Keywords.
* operator:                              operator.
* operator, Subroutine Declaration, Source Structure: The Operator.
* Operators:                             Operators.
* operators, built-in:                   Built-in Operators.
* operators, user-defined:               User-defined Operators.
* options, command line:                 Invoking GPC.
* or <1>:                                Keywords.
* or <2>:                                or.
* or:                                    Operations for Integer and Ordinal Types.
* or else:                               or else.
* or_else <1>:                           Keywords.
* or_else:                               or_else.
* Ord:                                   Ord.
* Ordinal Types, Intrinsic, Data Types:  Ordinal Types.
* OS/2:                                  MS-DOS or OS/2 with EMX.
* otherwise <1>:                         Keywords.
* otherwise:                             otherwise.
* Output:                                Output.
* output file option:                    GPC Options.
* Override:                              Override.
* Pack:                                  Pack.
* packed <1>:                            Keywords.
* packed:                                packed.
* Page:                                  Page.
* PAnsiChar:                             PAnsiChar.
* ParamCount <1>:                        ParamCount.
* ParamCount:                            Accessing Command Line Arguments.
* Parameter List, Subroutine Declaration, Source Structure: Subroutine Parameter List Declaration.
* parameter passing, internals:          Parameter passing.
* parameter, protected:                  Protected Parameters.
* ParamStr <1>:                          ParamStr.
* ParamStr:                              Accessing Command Line Arguments.
* parser, internals:                     Language definition.
* PChar:                                 PChar.
* Pi:                                    Pi.
* Pointer:                               Pointer.
* pointer arithmetics:                   Pointer Arithmetics.
* pointer types:                         Pointer Types.
* Pointer, Intrinsic, Data Types:        Pointer (Intrinsic).
* Polar <1>:                             Polar.
* Polar:                                 Complex Number Operations.
* Pos:                                   Pos.
* Position <1>:                          Position.
* Position:                              File Routines.
* pow <1>:                               Keywords.
* pow <2>:                               pow.
* pow:                                   Complex Number Operations.
* Pred <1>:                              Pred.
* Pred:                                  Operations for Integer and Ordinal Types.
* preprocessor:                          Compiler Directives.
* private <1>:                           Keywords.
* private:                               private.
* procedural parameters, internals:      Parameter passing.
* procedural type:                       Procedural Types.
* procedure <1>:                         Keywords.
* procedure:                             procedure.
* Procedure Call, Statements, Source Structure: Procedure Call.
* procedure, Subroutine Declaration, Source Structure: The Procedure.
* procedures, predefined:                Library Routines.
* program <1>:                           Keywords.
* program:                               program.
* programming in GPC:                    Programming.
* Programs, source structure:            The Program.
* property <1>:                          Keywords.
* property:                              property.
* protected <1>:                         Keywords.
* protected <2>:                         protected.
* protected:                             Importing Libraries from Other Languages.
* protected, parameter:                  Protected Parameters.
* PtrCard:                               PtrCard.
* PtrDiffType:                           PtrDiffType.
* PtrInt:                                PtrInt.
* PtrWord:                               PtrWord.
* public <1>:                            Keywords.
* public:                                public.
* published <1>:                         Keywords.
* published:                             published.
* Put <1>:                               Put.
* Put:                                   File Routines.
* qualified <1>:                         Keywords.
* qualified:                             qualified.
* Questions, Frequently Asked:           FAQ.
* Random:                                Random.
* Randomize:                             Randomize.
* Re <1>:                                Re.
* Re:                                    Complex Number Operations.
* Read:                                  Read.
* ReadLn:                                ReadLn.
* ReadStr:                               ReadStr.
* Real <1>:                              Real.
* Real:                                  Real Types.
* record <1>:                            Keywords.
* record:                                record.
* Record Types, Data Types:              Record Types.
* record, variant:                       Variant Records.
* register:                              register.
* Release:                               Release.
* Rename:                                Rename.
* repeat <1>:                            Keywords.
* repeat:                                repeat.
* repeat, Statements, Source Structure:  repeat Statement.
* Reset:                                 Reset.
* resident <1>:                          Keywords.
* resident:                              resident.
* restricted <1>:                        Keywords.
* restricted:                            restricted.
* Result:                                Result.
* Return:                                Return.
* ReturnAddress:                         ReturnAddress.
* Rewrite:                               Rewrite.
* RmDir:                                 RmDir.
* Root:                                  Root.
* Round:                                 Round.
* routines, predefined:                  Library Routines.
* Run Time Library <1>:                  Run Time System.
* Run Time Library:                      Library Routines.
* Run Time System <1>:                   Run Time System.
* Run Time System:                       Library Routines.
* RunError:                              RunError.
* schemata:                              Schema Types.
* Seek:                                  Seek.
* SeekRead <1>:                          SeekRead.
* SeekRead:                              File Routines.
* SeekUpdate <1>:                        SeekUpdate.
* SeekUpdate:                            File Routines.
* SeekWrite <1>:                         SeekWrite.
* SeekWrite:                             File Routines.
* segment <1>:                           Keywords.
* segment:                               segment.
* Self:                                  Self.
* set <1>:                               Keywords.
* set:                                   set.
* Set Types, Data Types:                 Set Types.
* SetFileTime:                           SetFileTime.
* SetLength:                             SetLength.
* SetType:                               SetType.
* shl <1>:                               Keywords.
* shl <2>:                               shl.
* shl:                                   Operations for Integer and Ordinal Types.
* ShortBool:                             ShortBool.
* ShortCard:                             ShortCard.
* ShortInt:                              ShortInt.
* ShortReal <1>:                         ShortReal.
* ShortReal:                             Real Types.
* ShortWord:                             ShortWord.
* shr <1>:                               Keywords.
* shr <2>:                               shr.
* shr:                                   Operations for Integer and Ordinal Types.
* Sin <1>:                               Sin.
* Sin:                                   Complex Number Operations.
* Single <1>:                            Single.
* Single:                                Real Types.
* SizeOf:                                SizeOf.
* SizeType:                              SizeType.
* SmallInt:                              SmallInt.
* source distributions, installing:      Compiling GPC.
* source structures:                     Source Structures.
* Sqr <1>:                               Sqr.
* Sqr:                                   Complex Number Operations.
* SqRt <1>:                              SqRt.
* SqRt:                                  Complex Number Operations.
* StandardError:                         StandardError.
* StandardInput:                         StandardInput.
* StandardOutput:                        StandardOutput.
* Statements, Source Structures:         Statements.
* static <1>:                            Keywords.
* static:                                static.
* StdErr:                                StdErr.
* Str:                                   Str.
* String:                                String.
* String, Intrinsic, Data Types:         String Types.
* String2CString:                        String2CString.
* subrange types:                        Subrange Types.
* Subroutine Declaration, Source Structures: Subroutine Declaration.
* SubStr:                                SubStr.
* Succ <1>:                              Succ.
* Succ:                                  Operations for Integer and Ordinal Types.
* support:                               Support.
* Text:                                  Text.
* TextWritable:                          TextWritable.
* TFDD:                                  TFDDs.
* then <1>:                              Keywords.
* then:                                  then.
* Time <1>:                              Time.
* Time:                                  Date And Time Routines.
* TimeStamp:                             TimeStamp.
* to <1>:                                Keywords.
* to:                                    to.
* to begin do:                           to begin do.
* to end do:                             to end do.
* tree nodes, internals:                 Tree nodes.
* Trim:                                  Trim.
* True:                                  True.
* Trunc:                                 Trunc.
* Truncate:                              Truncate.
* type <1>:                              Keywords.
* type:                                  type.
* type casts:                            Type Casts.
* Type Declaration, Source Structures:   Type Declaration.
* Type Definition Possibilities:         Type Definition Possibilities.
* type of:                               type of.
* TypeOf:                                TypeOf.
* types, functional:                     Procedural Types.
* types, initializers:                   Type Initializers.
* types, Integer:                        Integer Types.
* types, pointer:                        Pointer Types.
* types, procedural:                     Procedural Types.
* types, real:                           Real Types.
* types, restricted:                     Restricted Types.
* types, schema:                         Schema Types.
* types, schemata:                       Schema Types.
* types, subrange:                       Subrange Types.
* types, variant records:                Variant Records.
* UnBind:                                UnBind.
* Unbind:                                File Routines.
* unit <1>:                              Keywords.
* unit:                                  unit.
* Units, source structure:               Units.
* Unpack:                                Unpack.
* until <1>:                             Keywords.
* until:                                 until.
* UpCase:                                UpCase.
* Update <1>:                            Update.
* Update:                                File Routines.
* uses <1>:                              Keywords.
* uses:                                  uses.
* Val:                                   Val.
* value <1>:                             Keywords.
* value:                                 value.
* var <1>:                               Keywords.
* var:                                   var.
* var, Statements, Source Structure:     The Declaring Statement.
* Variable Declaration, Source Structures: Variable Declaration.
* view <1>:                              Keywords.
* view:                                  view.
* virtual <1>:                           Keywords.
* virtual:                               virtual.
* VMT:                                   Exporting GPC Libraries to Other Languages.
* Void:                                  Void.
* volatile <1>:                          Keywords.
* volatile:                              volatile.
* while <1>:                             Keywords.
* while:                                 while.
* while, Statements, Source Structure:   while Statement.
* Windows 95/98/NT, MS <1>:              MS Windows 95/98/NT.
* Windows 95/98/NT, MS:                  Download.
* with <1>:                              Keywords.
* with:                                  with.
* with, Statements, Source Structure:    with Statement.
* Word:                                  Word.
* WordBool:                              WordBool.
* Write:                                 Write.
* WriteLn:                               WriteLn.
* WriteStr:                              WriteStr.
* xor <1>:                               Keywords.
* xor <2>:                               xor.
* xor:                                   Operations for Integer and Ordinal Types.



Tag Table:
Node: Top1522
Node: Welcome3035
Node: Highlights7630
Node: News18715
Node: News - General Changes And Possible Incompatibilies with Previous Versions19673
Node: News - Command Line Options and Compiler Directives25028
Node: News - Compiler and RTS Built-in Declarations29345
Node: News - Units36760
Node: News - GPC Manual42699
Node: News - Demo Programs44926
Node: News - Test Suite45533
Node: Legend47155
Node: FAQ47421
Node: GNU Pascal48158
Node: What and why48520
Node: Current version49794
Node: Turbo Pascal compatibility50495
Node: Supported platforms51367
Node: Installing GPC52645
Node: Documentation files53388
Node: Components53911
Node: Debugger54547
Node: Libraries56555
Node: Contributed units60456
Node: IDE61684
Node: GPC on DJGPP62785
Node: What is DJGPP63702
Node: DJGPP FAQ64242
Node: DJGPP download64731
Node: Installing GPC on DJGPP65444
Node: DJGPP Info reader67563
Node: DJGPP DPMI server67881
Node: Assembler syntax68314
Node: DJGPP specific code69132
Node: DJGPP stack size71615
Node: Strings in GPC72562
Node: String schema73022
Node: Strings in variant records73987
Node: Length byte75892
Node: Short strings76662
Node: C strings77565
Node: Getting Help79078
Node: Miscellaneous FAQ79776
Node: Contributing80068
Node: GPC FTP and WWW sites80336
Node: About the FAQ80986
Node: Installation81923
Node: Download82461
Node: Binary Distributions88488
Node: Compiling GPC90799
Node: Compilation Notes98722
Node: MS-DOS with DJGPP99150
Node: MS-DOS or OS/2 with EMX100135
Node: MS Windows 95/98/NT100687
Node: Cross-Compilers101459
Node: Crossbuilding102744
Node: Borland Pascal103586
Node: BP Compatibility104912
Node: BP Incompatibilities106307
Node: String type108083
Node: Qualified identifiers110135
Node: Assembler110562
Node: Move; FillChar111712
Node: Real type112354
Node: Graph unit113509
Node: OOP units113897
Node: Keep; GetIntVec; SetIntVec114262
Node: TFDDs115094
Node: Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc.115605
Node: Endianness assumptions117335
Node: - -borland-pascal - disable GPC extensions120194
Node: -w - disable all warnings120932
Node: - -uses=System - Swap; HeapError; etc.121408
Node: -D__BP_TYPE_SIZES__ - small integer types etc.122031
Node: - -pack-struct - disable structure alignment122776
Node: -D__BP_RANDOM__ - BP compatible pseudo random number generator123441
Node: -D__BP_UNPORTABLE_ROUTINES__ - Intr; DosVersion; etc.124480
Node: IDE versus command line125543
Node: Comments130228
Node: BP Compatible Compiler Directives131649
Node: Units; GPI files and AutoMake132095
Node: Optimization135143
Node: Debugging136136
Node: Objects137037
Node: Strings in BP and GPC137598
Node: Typed Constants139662
Node: Bit; Byte and Memory Manipulation141406
Node: User-defined Operators in GPC144341
Node: Data Types in BP and GPC145088
Node: Files148983
Node: Built-in Constants149727
Node: Built-in Operators in BP and GPC150107
Node: Built-in Procedures and Functions150960
Node: Special Parameters152342
Node: Miscellaneous153484
Node: BP and Extended Pascal155908
Node: Portability hints158372
Node: Invoking GPC163838
Node: GPC Command Line Options166006
Node: GPC Options174803
Node: Programming183672
Node: Source Structures185264
Node: The Program186425
Node: Label Declaration188020
Node: Constant Declaration188417
Node: Type Declaration192573
Node: Variable Declaration195356
Node: Subroutine Declaration196960
Node: The Procedure197239
Node: The Function198061
Node: The Operator199521
Node: Subroutine Parameter List Declaration199841
Node: Statements202021
Node: Assignment202450
Node: begin end Compound Statement202973
Node: if Statement203454
Node: case Statement204215
Node: for Statement206093
Node: while Statement208198
Node: repeat Statement208709
Node: asm Inline209245
Node: with Statement209688
Node: goto Statement209830
Node: Procedure Call210065
Node: The Declaring Statement210429
Node: Loop Control Statements211573
Node: Modules and Units212025
Node: Modules212340
Node: Units216162
Node: Data Types218329
Node: Type Definition219260
Node: Ordinal Types219772
Node: Integer Types220521
Node: Natural Integer Types221307
Node: Main Branch Integer Types222229
Node: Integer Types with Specified Size223951
Node: Integer Types and Compatibility225281
Node: Summary of Integer Types226803
Node: Real Types229256
Node: String Types231006
Node: Character Types231868
Node: File Types232090
Node: Boolean (Intrinsic)232307
Node: Pointer (Intrinsic)233034
Node: Type Definition Possibilities233425
Node: Subrange Types234241
Node: Enumerated Types235511
Node: Array Types236397
Node: Record Types237510
Node: Variant Records239149
Node: Schema Types240165
Node: Set Types247261
Node: Pointer Types248400
Node: Procedural Types250193
Node: Object Types252873
Node: Type Initializers253092
Node: Restricted Types254749
Node: Machine-dependent Type Implementation256924
Node: Endianness257267
Node: Alignment260883
Node: Operators261051
Node: Built-in Operators261388
Node: User-defined Operators262317
Node: Parameters263727
Node: Protected Parameters264121
Node: Conformant Arrays264913
Node: Open Arrays265200
Node: Pointer Arithmetics265974
Node: Type Casts267288
Node: OOP274921
Node: Compiler Directives279838
Node: Library Routines287747
Node: File Routines288342
Node: String Operations293777
Node: Accessing Command Line Arguments296386
Node: Memory Management Routines297229
Node: Operations for Integer and Ordinal Types298396
Node: Complex Number Operations299746
Node: Set Operations301751
Node: Date And Time Routines302270
Node: Other Languages303005
Node: Importing Libraries from Other Languages303929
Node: Exporting GPC Libraries to Other Languages307687
Node: Notes for Debugging309939
Node: Run Time System311033
Node: GPC Units400330
Node: CRT402428
Node: Dos440061
Node: DosUnix450115
Node: FileUtils454806
Node: GMP461230
Node: GPCUtil492241
Node: HeapMon501185
Node: MD5503989
Node: Overlay507465
Node: Pipe509959
Node: Ports518769
Node: Printer522019
Node: RegEx526259
Node: Strings539338
Node: StringUtils543733
Node: System553772
Node: Trap567028
Node: Turbo3570721
Node: WinDos573123
Node: Reference580849
Node: Abs584930
Node: absolute586137
Node: abstract589203
Node: Addr589432
Node: AlignOf590197
Node: all591031
Node: and591976
Node: and then594609
Node: and_then595421
Node: AnsiChar597490
Node: Append598241
Node: ArcTan599520
Node: Arg600296
Node: array600994
Node: asm602240
Node: asmname602743
Node: Assign604676
Node: Assigned605090
Node: attribute606078
Node: begin606355
Node: Bind607175
Node: bindable607504
Node: Binding607791
Node: BindingType608133
Node: BitSizeOf610459
Node: BlockRead611462
Node: BlockWrite611943
Node: Boolean612435
Node: Break613016
Node: Byte614093
Node: ByteBool614956
Node: ByteCard615387
Node: ByteInt616192
Node: C617058
Node: Card617339
Node: Cardinal617937
Node: case619389
Node: Char621574
Node: ChDir622031
Node: Chr622873
Node: C_Language623441
Node: class623737
Node: Close623960
Node: Cmplx624220
Node: Comp624792
Node: Complex625578
Node: Concat626165
Node: Conjugate626554
Node: const627320
Node: constructor627644
Node: Continue627933
Node: Copy628810
Node: Cos630320
Node: CString631043
Node: CString2String631447
Node: CStringCopyString631759
Node: Date632103
Node: Dec632406
Node: DefineSize633811
Node: Delete634168
Node: destructor634508
Node: Dispose634793
Node: div635357
Node: do635711
Node: Double636488
Node: downto637055
Node: else637536
Node: Empty638898
Node: end639163
Node: EOF640137
Node: EOLn640515
Node: EpsReal640902
Node: Eq641180
Node: Erase641489
Node: Exclude641791
Node: Exit642015
Node: Exp643172
Node: export644021
Node: exports644299
Node: Extend644570
Node: Extended644839
Node: extern645221
Node: external645449
Node: Fail645677
Node: False645896
Node: far646112
Node: file646940
Node: FileMode647216
Node: FilePos647527
Node: FileSize647854
Node: FillChar648185
Node: Flush648592
Node: for648853
Node: forward650492
Node: Frac650714
Node: FrameAddress650976
Node: FreeMem651217
Node: function652088
Node: GE652315
Node: Get652571
Node: GetMem652823
Node: GetTimeStamp654274
Node: goto654625
Node: GT654942
Node: Halt655195
Node: High655883
Node: if657311
Node: Im658798
Node: implementation659372
Node: import659616
Node: in661019
Node: Inc661228
Node: Include662681
Node: Index662904
Node: inherited663129
Node: inline663361
Node: InOutRes663590
Node: InOutResStr663861
Node: Input664140
Node: Insert664396
Node: Int664694
Node: Integer664946
Node: interface666142
Node: interrupt666379
Node: IOResult666616
Node: is666879
Node: label667091
Node: LastPosition667314
Node: LE667609
Node: Length667872
Node: library668137
Node: Ln668359
Node: LoCase669104
Node: LongBool669366
Node: LongCard669805
Node: LongestBool670606
Node: LongestCard671074
Node: LongestInt671860
Node: LongestReal672671
Node: LongestWord673124
Node: LongInt673927
Node: LongReal674811
Node: LongWord675203
Node: Low676006
Node: LT677205
Node: Mark677457
Node: Max677707
Node: MaxChar677983
Node: MaxInt678207
Node: MaxReal678433
Node: MedBool678661
Node: MedCard679092
Node: MedInt679959
Node: MedReal680799
Node: MedWord681172
Node: Min682042
Node: MinReal682321
Node: MkDir682544
Node: mod683369
Node: module683632
Node: Move683851
Node: MoveLeft684134
Node: MoveRight684432
Node: Name684733
Node: NE684950
Node: near685203
Node: New686025
Node: NewCString686842
Node: nil687126
Node: not688600
Node: Null688937
Node: object690443
Node: Odd691243
Node: of691971
Node: only692178
Node: operator692394
Node: or692618
Node: or else695212
Node: Ord695986
Node: or_else696336
Node: otherwise698256
Node: Output698490
Node: Override698750
Node: Pack698978
Node: packed699337
Node: Page701085
Node: PAnsiChar701369
Node: ParamCount701786
Node: ParamStr702615
Node: PChar703128
Node: Pi703553
Node: Pointer703765
Node: Polar704194
Node: Pos704461
Node: Position704738
Node: pow705007
Node: Pred705365
Node: private707430
Node: procedure707807
Node: program708042
Node: property708274
Node: protected708507
Node: PtrCard709060
Node: PtrDiffType709531
Node: PtrInt710035
Node: PtrWord710497
Node: public710937
Node: published711314
Node: Put711693
Node: qualified711955
Node: Random712185
Node: Randomize712415
Node: Re712644
Node: Read713152
Node: ReadLn713509
Node: ReadStr713822
Node: Real714101
Node: record714467
Node: register717033
Node: Release717264
Node: Rename717531
Node: repeat717815
Node: Reset718829
Node: resident719157
Node: restricted719389
Node: Result719627
Node: Return719855
Node: ReturnAddress720086
Node: Rewrite720332
Node: RmDir720674
Node: Root721511
Node: Round721727
Node: RunError722474
Node: Seek722748
Node: SeekRead723034
Node: SeekUpdate723334
Node: SeekWrite723645
Node: segment723952
Node: Self724179
Node: set724395
Node: SetFileTime724680
Node: SetLength725052
Node: SetType726360
Node: shl728534
Node: ShortBool729487
Node: ShortCard729932
Node: ShortInt730726
Node: ShortReal731581
Node: ShortWord731981
Node: shr732922
Node: Sin734099
Node: Single734817
Node: SizeOf735076
Node: SizeType735722
Node: SmallInt736168
Node: Sqr736918
Node: SqRt737779
Node: StandardError738837
Node: StandardInput739087
Node: StandardOutput739347
Node: static739602
Node: StdErr739834
Node: Str740626
Node: String741403
Node: String2CString741632
Node: SubStr741938
Node: Succ743155
Node: Text745209
Node: TextWritable745612
Node: then745850
Node: Time746272
Node: TimeStamp746568
Node: to747929
Node: to begin do748149
Node: to end do748387
Node: Trim748623
Node: True748883
Node: Trunc749098
Node: Truncate749695
Node: type749966
Node: type of752345
Node: TypeOf752570
Node: UnBind753628
Node: unit753892
Node: Unpack754110
Node: until754476
Node: UpCase754807
Node: Update755070
Node: uses755399
Node: Val756757
Node: value757154
Node: var757676
Node: view759792
Node: virtual760007
Node: Void760230
Node: volatile760688
Node: while760915
Node: with761852
Node: Word762182
Node: WordBool763464
Node: Write763892
Node: WriteLn764308
Node: WriteStr764674
Node: xor764981
Node: Keywords766460
Node: Support775236
Node: Mailing List776771
Node: Mailing List Archives778461
Node: Newsgroups779787
Node: Professional Support781045
Node: Compiler Crashes781786
Node: Reporting Bugs782416
Node: Testing788341
Node: To Do790281
Node: Known Bugs791947
Node: Urgent793381
Node: Bugs795013
Node: Planned Features800326
Node: Planned - Strings801470
Node: Planned - Records/arrays803620
Node: Planned - Files804827
Node: Planned - Other types805616
Node: Planned - Units and modules806945
Node: Planned - OOP808508
Node: Planned - Misc811376
Node: Planned - Utilities814834
Node: Done815206
Node: Fixed Bugs815481
Node: Implemented Features855882
Node: Internals884130
Node: Lexical analyzer886847
Node: Language definition889170
Node: Tree nodes892963
Node: Parameter passing897784
Node: GPI files900099
Node: AutoMake904409
Node: File Layout906967
Node: Contributors909661
Node: Copying920347
Node: GNU939543
Node: Manifesto942421
Node: Gnu is Not Unix943712
Ref: Gnu is Not Unix-Footnote-1946072
Node: Why GNU946962
Node: GNU Unix Compatibility948036
Node: GNU Availability948486
Node: Why Help GNU948952
Node: How To Contribute to GNU950353
Node: GNU Benefits952180
Ref: GNU Benefits-Footnote-1954439
Node: Objections to GNU954713
Ref: Objections to GNU-Footnote-1969215
Ref: Objections to GNU-Footnote-2969257
Ref: Objections to GNU-Footnote-3969777
Node: Funding969883
Node: GPC Index972359

End Tag Table
